TAT.cooperliang First Meaningful Paint 首次有效绘制时间
In 未分类 on 2019年12月31日 by view: 6,889
3

前言

最近在研究网站测速相关的主题,接触到一个概念:First Meaningful Paint,简称 FMP,中文译名:首次有效绘制时间。今天我们来讲讲这个概念的来龙去脉。

衡量页面打开速度是一件复杂的事情

First Meaningful Paint(以下简称 FMP),是谷歌创造的一个概念,用来更好地衡量页面打开的速度。你可能会说,要衡量页面打开速度,不是已经有 DOMContentLoaded EventOnLoad Event 了吗?为什么还要搞一个新概念?
答案是:因为随着 Web 应用越来越复杂,DOMContentLoaded Event 和 OnLoad Event 已经越来越难以准确表现页面的打开速度了。

举个例子:

在这个例子中,html 中有直出的内容,也有一张图片,script 中用 setTimeout 模拟一个 Ajax 请求,数据返回后插入到页面中。像这种类型的页面非常常见,我们通过 Chrome 的 Performance 可以看到它的打开效果和速度。

Demo

image

观察 Timings,可以看到在打开页面的过程中依次触发了 DOMContentLoaded -> First Paint ->First Contentful Paint -> OnLoad -> First Meaningful Paint。我们尝试来解释一下。

  1. 浏览器首先加载解析 HTML,HTML 加载解析完成后,触发 DOMContentLoaded Event。此时浏览器尚未开始渲染,其他静态资源,比如图片等也还没加载。
  2. 浏览器开始渲染直出的 HTML,触发 First PaintFirst Contentful Paint,用户开始看到文字。此时图片尚未加载回来,所以还不能看到图片。
    PS:关于 First Paint 和 First Contentful Paint,网上的资料很少,我也没完全搞明白这两者的定义和区别。我大致是这样理解的:浏览器要开始渲染的时候,会先触发 First Paint,当渲染出第一个 DOM(比如文字或者图片等 DOM 元素)的时候,就会触发 First Contentful Paint。这两个概念并非本文的重点,更多的详细解析,请参考 W3C 的定义
  3. 浏览器把图片加载回来了,所有资源都加载完成,触发 OnLoad Event
  4. setTimeout 定时器触发,往页面中写入大量 DOM,触发 First Meaningful Paint

那么问题来了,这里有 5 个指标,应该用哪个指标来衡量页面打开速度呢?
DOMContentLoaded 肯定不行,因为页面都还没出来;First Paint 和 First Contentful Paint 也不够好,因为这时候只有文字,图片和异步的数据都没出来。虽然从技术上角度看,页面是打开了。但是对于用户来说,用户想要关注的是下面的异步数据,异步数据还没出来,用户自然认为页面还没打开。OnLoad 也不够好,因为虽然图片出来了,但是异步数据还是没出来。
那哪个指标才能衡量异步数据出来的时间的呢? -> 从 Performance 中可以看出,这个指标就是 First Meaningful Paint,它最接近用户感知上的打开时间,所以它的名字叫 Meaningful,意思就是,对于用户来说,是有意义的,有效的。

综上所述,页面打开是一个非常复杂的过程,在这个过程中,有很多指标可以来表征页面打开不同阶段的情况。其中,最接近用户实际感知的,就是 First Meaningful Paint。
那么,下一个问题来了,这个 First Meaning Paint 是怎么定义的?Chrome 又是如何找到这个时间点的呢?

猜想,验证,优化

如果这个 Demo 就是我们的实际业务,想要衡量这个业务的打开速度,由于我们知晓其中的逻辑,知道只要等到那个 Ajax 回来之后,对于用户而言,就是 First Meaningful Time 了。所以我们可以通过自己打点来算出这个时间点。
问题:如果想要做一个通用化的工具,用来测量不同网站的 First Meaningful Time 呢?就跟 Chrome 的 Performance 一样,我们不可能知晓别的网站的业务逻辑,自然无法准确定义,到底哪个时刻才是 First Meaningful Time。怎么办呢?
答案:虽然无法准确知晓,但是可以靠猜测,关键是:怎么样猜测?猜得准不准?多准算准呢?

猜想一:布局重绘变化最大

在我们这个 Demo 中,异步数据回来后,会往页面中插入大量 DOM,势必会触发布局的重绘。浏览器可以检测出,什么时候发生最大的布局重绘变化,那么这个时刻就可以认为用户看到了关键内容,也就是 First Meaningful Paint 了。最大布局重绘变化,说起来比较抽象,可以通过另一个更加直观的指标来近似表征,就是页面中 DOM 节点的数量。下图便是 Demo 的 DOM 元素数量变化图。可以观察到,对应的时间是近似等于 First Meaningful Paint。

image

猜想二:考虑很长的页面

我们把 Demo 变一下,代码如下所示