Chrome 中的 First Meaningful Paint
在做网页的性能监控时,首屏加载时间是必不可少的统计项。但是到底如何算是首屏呢?怎么能更好的统计首屏时间呢?lighthouse中的First Meaningful Paint或许能给我们启发。
Chrome 60中正式引入了lighthouse,放在了devtool的audit面板中。lighthouse可以用来对页面进行审查,得到性能等一些数据,最近在看其源码,感觉可以帮助对浏览器渲染页面等有更深的理解,以后可以详细介绍一下。今天要说的是lighthouse中的First Meaningful Paint。
First Meaningful Paint简介
First Meaningful Paint,是lighthouse中performance下的一项审查,可以用来衡量页面的渲染性能。
First Meaningful Paint是指页面的首要内容(primary content)出现在屏幕上的时间。对于不同的站点,首要内容是不同的,例如:
- 对于博客文章:大标题+首屏文字是首要内容
- 对于百度或者google的搜索结果页:首屏的结果卡片就是首要内容
- 而对于淘宝等购物网站来说:图也会变得很重要
需要注意的是,通常首要内容是不包括headers和导航条的。
基本计算方法:计算布局对象
在Chrome浏览器中进行渲染时,布局对象会不断地增加到布局树中:
随着布局对象的增加,页面也会一点点被加载出来:
该算法的作者通过观察发现,布局对象的变化跟页面渲染进度非常相关。布局对象变化最显著的时间,与页面主体渲染出的时间非常接近。
于是,作者得到了基本算法,也就是:
首次有效绘制 = 具有最大布局变化的绘制
补充方法:启发法
当然事情没有这么简单,网站这么多种,总会有特例。作者用启发法来cover了一些特例。
长页面
首先是长页面,下图是新浪微博的渲染过程截图。
可以看到页面其实在很早就已经加载完成了,但是最大布局对象的变化发生在二十多秒。原因是微博进行了懒加载,将页面底部的内容,以及背景边框的加载进行了推迟。显然这些内容不能算作首要内容。为了cover这种情形,作者提出了布局显著性,页面越长,显著性系数越小。
布局显著性 = 添加的对象数目 / max(1, 页面高度 / 屏幕高度)
经过处理后,结果如下图所示:
变化最大的地方便接近了首次有效绘制的正确时间。
网页字体
有些网站会加载特殊的字体,例如msn:
最大布局改变时间发生在2.51s,但此时页面中并没有文字显示,因为字体还在加载中。
在文字加载过程中,浏览器会使用字体队列中后方的字体,但是在font block period中,并不会渲染。
显然文字对于页面的渲染非常重要,因此如果在布局发生时有字体正在渲染,那么会将时间推迟直到字体显示出来(字体加载成功了或者到达3秒使用了备用字体)。
实现
首次有效绘制很好,计算看起来也很简单,但是如何获得布局对象的数目呢?
作者实现了两种方法,lighthouse中使用的是chrome渲染过程中记录的trace event
结果
这种基于布局来近似计算首次有效渲染的方法,准确率可以达到77%。具体对比可以看https://docs.google.com/spreadsheets/d/1FEcDwXfgMf5rw1lNn07Cm04A-r7AdPzmt0aAufMsnnk/edit?usp=sharing