一、前端页面性能及其分析工具
前端页面的性能,一直都是大家持续关注的一个领域,因为用户的留存率和页面加载性能息息相关。根据google做出的数据统计,页面访问时长从1s增加到3s,用户跳出率增加32%。
对于前端页面性能的评估,一般是两种形式:一种是使用性能分析工具,在线对网页各项指标进行打分评估;一种是使用性能监控,通过 performance api 或者自定义的埋点上报用户网络真实的访问情况,然后进行统计分析。
虽然通过统计用户的数据更加真实,但是为了对页面性能能够有一个统一的量化标准,我们往往选择使用标准的打分工具对页面的性能进行评估。
性能分析初期,我们会从 chrome 的开发者工具对网页进行分析,包括查看 load 和 DOMContentLoaded 等事件触发的时间。后来又有了一系列的性能分析工具,例如 webpage analyzer、WebPageTest、Yslow等。
现在由于google官方已经将他们自己开发的 Lighthouse 嵌入到开发者工具的选项卡中,因此我们就把 Lighthouse 当做是标准评估工具。
Lighthouse 是一款开源的web页面性能分析工具,并且会给出页面最佳实践的一些相关建议。除了可以直接在 chrome DevTools 中使用外,也支持使用浏览器插件(chrome和Firefox)或者npm包(node api或者CLI)。
像google的网页 measure以及 PageSpeed Insight工具都是调用的 Lighthouse 对页面进行分析。
二、如何为页面的性能打分
1. Lighthouse 的迭代与性能指标变化
Lighthouse 第一个开源的版本可以追溯到2016年,目前(2020年10月)最新的版本是6.4.1,已经迭代89个版本。而在这几年中 Lighthouse 对于性能指标的选取也一直在更新。
google在最新的6.X版本中,相比于5.X版本,更新了三个新的性能指标:去掉了 FMP(First Meaningful Paint)、FCI(First CPU Idle) 和 mpFID(Max Potential First Input Delay);
加入了 TBT(Total Blocking Time)、LCP(Largest Contentful Paint) 和 CLS(Cumulative Layout Shift)。后文会针对这些指标进行详细的讲解。
之前5.X版本的Lighthouse
现在的Lighthouse(6.X版本)
2. 如何计算页面性能分数
如下图所示,在页面性能部分,Lighthouse 会综合目前的6个关键指标的表现情况,计算出页面的性能分数。
以最新的6.X计算方法来看,每个性能指标的数值会对应一个该指标的分数。例如上图中的FCP、SI、LCP、TTI、TBT、CLS等数值,对应的单项分数就依次为78、62、37、5、99、92分。一般来说数值越小该指标分数越高。
而这6个指标对应的权重分别为15%、15%、25%、15%、25%、5%,通过加权平均计算出性能总分为图中的60分。
如果想知道每个指标数值与其对应分数的具体计算方法,可以参考文章末尾的资料5和6。
三、关键的性能指标
在6.0版本的 Lighthouse 中,被去掉的关键性能指标分别是FMP(首次有意义的渲染帧)、FCI(首次CPU空闲)以及用户mpFID(潜在最大首次输入延迟)。
下面我们从这三个被废弃指标的定义开始切入,更好的理解现在版本的指标选取依据。
1. 什么是 FMP,和 FCP 有什么区别
说起FMP之前,我们必须要先介绍一下 First Contentful Paint(FCP):首次内容渲染时间。
如其名所示,只要首次触发了浏览器的 The First Page Paint 事件,此刻的时间点就是FCP。但此时渲染的不一定是重要的页面信息,比如仅仅是绘制了一个头部的 action bar 等,甚至不一定会渲染出可见的元素。虽然在Lighthouse6.0中得到了保留,但对性能得分的权重从23%降低到15%。
因此,FCP 不能作为一个从用户视角准确衡量页面性能好坏的指标。
在这个背景下,FMP(First Meaningful Paint:首次有意义的渲染帧)应运而生。根据官方的定义,FMP 是指从页面加载开始,到大部分或者主要内容已经在首屏上渲染的时间点。
那么 FMP 时间点是怎么确认的呢,我们先看下最基本的计算方法:
我们首先计算布局对象(layout objects)数量(使用 LayoutAnalyzer 测试计算,详见资料17)。
根据下图可以看出,页面加载的过程其实就是布局对象逐步进入 layout tree 并进行渲染的过程。
layoutAnalyzer 会收集 layout objects 数量,有一个计数器叫做
LayoutObjectsThatHadNeverHadLayout,即首次新增的 layout objects 的个数。
通过测试发现相比于其他计数器,它变化最大的时刻,往往就是页面最重要的元素渲染了的时刻。
因此 FMP 指标的计算方法为:LayoutObjectsThatHadNeverHadLayout(新增的布局对象)发生变化最大的下一个时刻(paint that follows biggest layout change)。
当然,也存在一些场景不适用上述的情况:
a)、如果页面为长页面,那么会存在不可见布局对象增加的个数比首屏内可见对象增加个数更多的情况,此时 FMP 就是不准确的
b)、有加载web字体的情况,文字会使用降级字体进行布局,但是默认在 loadstart 开始的3s内,不进行绘制,这样也会影响FMP的计算
针对场景1,FMP 通过引入了 layout signifcance(布局重要度)的概念来解决该问题;针对场景2,FMP 通过推迟统计的时间,来让指标更加合理反映页面的情况。更加详细的解决方案可以参考资料18。
google也针对上述 FMP 的不同场景对近200个页面做了试验,通过人工看页面截图,与用户感受到的 FMP 准确度做对比,结果如下:
不过最终 FMP 在6.0的时候被废弃,主要是因为以下两点:
-
在生产环境中,FMP 对页面细微的变化太过敏感,容易导致结果不一致。
-
该指标的定义比较依赖于浏览器具体的实现细节,不具有可参考的标准性。
2. 代替 FMP 的 LCP 来了
上一个小章节中提到的了 FCP、FMP 的不足,因此W3C的性能小组也一直在想找一个合适的指标,更加真实反映用户看到页面主要内容的时间。
有时候简单点也许会更好(Sometimes simpler is better),根据多方关于页面性能的讨论,终于找到了一个更加准确衡量页面主要内容是否加载的方法,那就是 LCP(Largest Contentful Paint)。
LCP 指的是在视窗内,最大的内容元素被渲染的时间。这个指标在 Lighthouse 6.0中也正式加入,并且在最终性能评分中,有高达25%的权重。
LCP 应该是除了FCP以外最容易定义的指标,从定义可以看出,关键点就2个,选取哪些元素进行比较和如何确定元素的大小。
根据官方文档,下列元素会被纳入Largest Contentful 元素的考虑范围:
-
-
通过 url() 函数加载背景图片的元素
-
包含 text node 的块级元素或者 inline text 的子元素
那我们如何确定元素的大小?主要是以下 4 个规则:
-
在 viewport 内可见元素的大小,如果是超出可视区域或者被裁减、遮挡等,都不算入该元素大小
-
对于图片元素来说,大小是取图片实际大小和原始大小的较小值,即Min(实际大小,原始大小)
-
对于文字元素,只取能够覆盖文字的最小矩形面积
-
对所有元素,margin、padding、border 等都不算
google对该指标的评价如下:LCP 是一个十分重要并且以用户感受为中心的指标;它反映了感知层面上页面的加载速度;它标记了页面主要内容中最大内容元素加载完成的时间点;LCP 较短的页面能够让用户更快感觉到页面是可用的。
3. 被废弃的 FCI 是什么,为什么和 TTI 联系这么紧密
FCI(First Cpu Idle:首次CPU空闲),这个指标用来衡量一个页面需要多久才能达到 minimally interactive(最低限度交互)的标准。
而最低可交互的确认需要同时满足以下两个条件:
a) 大部分在屏幕上的 UI元素都是可交互的
b) 页面对大部分用户的输入响应,平均时间在一个合理的范围内
TTI(Time To Interactive:页面可交互时间),指的是页面达到完全可交互状态所需要的时间。
完全可交互指的是同时满足下面三个条件:
a) FCP 之后,页面已经呈现了有用的内容
b) 对大部分的可见页面元素而言,已经注册了事件回调
c) 页面对用户交互的响应在50ms以内
2017年,First Interactive 指标被分成了 First Interactive 和 Consistently Interactive 两个指标;第二年7月,First Interactive指标改名为 FCI,同时 Consistently Interactive 改名为 TTI 。可见,FCI 和 TTI 这两个指标是一对反映用户交互响应的指标。
那么最低可交互和完全可交互是怎么计算的呢?在介绍具体的计算方法之前,我们需要知道这两个指标都是模糊的并且在不同的情况下可以持续被优化改进的。
- FCI 的最低限度可交互时间
在主线程的时间线中,从 FMP 开始且某个任务结束后,寻找到长度为 f(t) 的时间窗口 W。如果 W 满足在其任意时间段内,没有长度大于250ms的连续任务集,且前后1s内都没有长任务(js执行时间超过50ms的任务为长任务),那么该任务结束的时刻就是我们定义的 FCI 。其中 f(t) = 4 * e^(-0.045 * t) + 1。
下图红框中所指的时间点即为 FCI
具体的推导过程可以参考资料11,可以更深刻的理解到为什么 FCI 是模糊的一个概念。
- TTI 的完全可交互时间
从网络和主线程的时间线中,找到第一个5s的窗口期 W,在 W 时间段满足:任意时刻没有超过两个同时进行中的网络请求、没有超过50ms的长任务。则W前的最后一个长任务结束时刻,就是我们说的 TTI。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分
CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-56WazfSW-1712013566172)]
紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分
CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】