编者按:本文作者Berwin,W3C性能工作组成员,360导航资深前端工程师。《深入浅出Vue.js》作者。
测量与排查网页的性能瓶颈,是一名专业Web性能优化者的基本功。本章将详细介绍Web性能领域的一些专业术语,通过这些术语也可以侧面了解是哪些因素在影响加载性能。
衡量网页的性能是一个比较琐碎的事情,因为没有某一个指标或数字可以直接告诉我们网页的性能怎样,因为加载网页不是一瞬间的事,准确地说,它是一个过程,不存在某个单独的 “时间点” 可以完全体现出网页的性能,因为在网页加载的过程中,有很多个比较关键的 “时间点” 可以影响用户的感觉(感觉我们的网页是 “快” 还是 “慢”)。而且不同类型的产品所侧重的点也都不太一样,可能同一个时间点,对于某些产品至关重要,但对于另外一些产品,则完全不care。
以https://www.google.com.hk为例,下图是使用Lighthouse(一个性能测评工具)捕获出的测评结果报告。
下图是使用Chrome浏览器的DevTools捕获出的加载性能结果报告。
从上面这两张性能测评报告中,我们会发现报告通常会给出很多个 “关键时间点” 来表示性能数据,单独的某个“时间点”无法体现出网页的性能,只有将它们与自身的产品类型相结合,综合评估,才能判断出网页的性能到底怎样。而我们要做的,就是读懂报告中的各种专业术语,并分辨出哪些因素影响了网页的加载性能。
从前面的评测报告中,我们会看到FP、FCP、FMP与LCP这几个字母很接近的术语,实际上他们的意思也非常接近,都表示浏览器在屏幕上渲染像素的时间点。F是First的首字母缩写,表示“第一次”;P是Paint的首字母缩写,表示“绘制”;C是Contentful的首字母缩写,表示“内容”。
FP(全称“First Paint”,翻译为“首次绘制”) 是时间线上的第一个“时间点”,它代表浏览器第一次向屏幕传输像素的时间,也就是页面在屏幕上首次发生视觉变化的时间。
注意:FP不包含默认背景绘制,但包含非默认的背景绘制。
FCP(全称“First Contentful Paint”,翻译为“首次内容绘制”),顾名思义,它代表浏览器第一次向屏幕绘制 “内容”。
注意:只有首次绘制文本、图片(包含背景图)、非白色的canvas或SVG时才被算作FCP。
FP与FCP这两个指标之间的主要区别是:FP是当浏览器开始绘制内容到屏幕上的时候,只要在视觉上开始发生变化,无论是什么内容触发的视觉变化,在这一刻,这个时间点,叫做FP。
相比之下,FCP指的是浏览器首次绘制来自DOM的内容。例如:文本,图片,SVG,canvas元素等,这个时间点叫FCP。
FP和FCP可能是相同的时间,也可能是先FP后FCP。
FMP(全称“First Meaningful Paint”,翻译为“首次有效绘制”) 表示页面的“主要内容”开始出现在屏幕上的时间点。它是我们测量用户加载体验的主要指标。
FMP本质上是通过一个算法来猜测某个时间点可能是FMP,所以有时候不准。
想详细了解FMP及它的原理可以看我的另一篇文章:《捕获FMP的原理》(https://github.com/berwin/Blog/issues/42)
图3给出了FP、FCP、FMP之间的比较。
LCP(全称“Largest Contentful Paint”) 表示可视区“内容”最大的可见元素开始出现在屏幕上的时间点。
了解和测量网站真实的性能其实非常困难,像load和DOMContentLoaded不会告诉我们用户什么时候可以在屏幕上看到内容。而FP和FCP又只能捕获整个渲染过程的最开始,FMP更好一点,但是它的算法比较复杂,而且前面说了,有时候不准。
根据W3C Web性能工作组的讨论和Google的研究,发现测量页面主要内容的可见时间有一种更精准且简单的方法是查看什么时候渲染最大元素。
以上图为例,绿色方块的区域是内容最大的元素,所以在这个例子中,LCP等于这个元素开始渲染的时间。
现在我们了解了FP、FCP、FMP以及LCP这几个术语,FP与FCP可以让我们知道,我们的产品何时开始渲染;而FMP与LCP可以让我们了解我们的产品何时“有用”,站在用户的角度,FMP与LCP可以表示我们的产品需要多久才能体现出价值。
注意,这里说的是“有用”,而不是“能用”;那我们如何才能知道我们的产品什么时候“能用”呢?这就需要另一个性能指标“TTI”了。
TTI(全称“Time to Interactive”,翻译为“可交互时间”) 表示网页第一次 完全达到可交互状态 的时间点。可交互状态指的是页面上的UI组件是可以交互的(可以响应按钮的点击或在文本框输入文字等),不仅如此,此时主线程已经达到“流畅”的程度,主线程的任务均不超过50毫秒。TTI很重要,因为TTI可以让我们了解我们的产品需要多久可以真正达到“可用”的状态。
关于50毫秒的问题我之前的博客文章有多次提到,可以参考这篇文章《时间切片(Time Slicing)》(https://github.com/berwin/Blog/issues/38)
TTFB(全称“Time to First Byte”) 表示浏览器接收第一个字节的时间
FCI(全称“First CPU Idle”) 是对TTI的一种补充,TTI可以告诉我们页面什么时候完全达到可用,但是我们不知道浏览器第一次可以响应用户输入是什么时候。我们不知道网页的“最小可交互时间”是多少,最小可交互时间是说网页的首屏已经达到了可交互的状态了,但整个页面可能还没达到。从名字也可以看出这个指标的意思,第一次CPU空闲,主线程空闲就代表可以接收用户的响应了。
更通俗的理解TTI与FCI的区别:FCI代表浏览器真正的第一次可以响应用户的输入,而TTI代表浏览器已经可以持续性的响应用户的输入。
FID(全称“First Input Delay”,翻译为“首次输入延迟”) 顾名思义,FID指的是用户首次与产品进行交互时,我们产品可以在多长时间给出反馈。TTI可以告诉我们网页什么时候可以开始流畅地响应用户的交互,但是如果用户在TTI的时间内,没有与网页产生交互,那么TTI其实是影响不到用户的,TTI是不需要用户参与的指标,但如果我们真的想知道TTI对用户的影响,我们需要FID。不同的用户可能会在TTI之前开始与网页产生交互,也可能在TTI之后才与网页产生交互。所以对于不同的用户它的FID是不同的。如果在TTI之前用户就已经与网页产生了交互,那么它的FID时间就比较长,而如果在TTI之后才第一次与网页产生交互,那么他的FID时间就短。
捕获FID比较简单,我们只需要在网页的head标签里注册一个事件(click、mousedown、keydown、touchstart、pointerdown),然后在事件响应函数中使用当前时间减去事件对象被创建的时间即可。
performance.now() - event.timeStamp
DCL 表示DomContentloaded事件触发的时间。
L 表示onLoad事件触发的时间。
DomContentloaded事件与onLoad事件的区别是,浏览器解析HTML这个操作完成后立刻触发DomContentloaded事件,而只有页面所有资源都加载完毕后(比如图片,CSS),才会触发onLoad事件。
Speed Index 表示显示页面可见部分的平均时间(注意,是真正的可见,用户可以立马看见的,屏幕外的部分不算),数值越小说明速度越快,它主要用于测量页面内容在视觉上填充的速度。通常会使用这个指标来进行性能的比较。比如优化前和优化后,我们的产品与竞品的性能比较等。但是只能用于 粗略 的比较,不同的产品侧重点完全不同,所以还是需要根据自己产品所侧重的方向,并结合其他指标来进行更详细的对比。
博客文章这样的页面更侧重FMP(用户希望尽快看到有价值的内容),而类似后台管理系统或在线PPT这种产品则更侧重TTI(用户希望尽快与产品进行交互)。
本文我们介绍了Web性能领域常见的专业术语,包括:FP、FCP、FMP、TTI、LCP、TTFB、FCI、FID、DCL、L、Speed Index。这些术语可以帮助我们理解性能报告给出的各种数据。
《奇舞周刊》是360公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。