最近参加了字节举办的《APMPlus前端监控训练营》,特此记录些指标,方便自己日后查阅。
一、性能指标
提供了文档导航过程中完整的计时信息,即一个文档从发起请求到加载完毕各阶段的性能耗时。
提供了获取各种类型(navigation、resource、paint 等)的性能时间线的方法。
提供文档中资源的计时信息。
记录在页面加载期间的一些关键时间点。
检测长任务的存在,长任务会在很长一段时间内独占UI线程,并阻止其他关键任务的执行——例如响应用户输入。
性能指标主要依赖 Navigation Timing 或者 Navigation Timing 2,通过记录一个文档从发起请求到加载完毕的各阶段的性能耗时,以加载速度来衡量性能。
各阶段计算方式和含义
二、用户指标
用户指标专注于用户视角下的浏览体验。
用户体验 |
指标 |
发生了吗? |
FP(First Paint ) FCP(First Contentful Paint ) |
内容有用吗? |
FMP(First Meaningful Paint ) SI(Speed Index) LCP (Largest Contentful Paint) |
内容可用吗? |
TTI(Time to Interactive ) TBT (Total Blocking Time) |
令人愉悦吗? |
FID(First Input Delay ) CLS(Cumulative Layout Shift) |
FP(First Paint)
首次渲染的时间点。 FP 时间点之前,用户看到的都是没有任何内容的白色屏幕。
FCP(First Contentful Paint)
首次有内容渲染的时间点。在用户访问 Web 网页的过程中,FCP 时间点之前,用户看到的都是没有任何实际内容的屏幕。FCP 反映当前 Web 页面的网络加载性能情况、页面 DOM 结构复杂度情况、inline script 的执行效率的情况。当所有的阶段性能做的非常好的情况下,首次出现内容的时间就会越短,用户等待的时间就会越短,流失的概率就会降低
FMP(First Meaningful Paint)
首次绘制有意义内容的时间点。FMP 通常被认为是用户获取到了页面主要信息的时刻,也就是说此时用户的需求是得到了满足的,所以产品通常也会关注 FMP 指标。
前端业界现在比较认可的一个计算 FMP 的方式就是:页面在加载和渲染过程中最大布局变动之后的那个绘制时间即为当前页面的 FMP。FMP代码实现原理:
认为「DOM 结构变化的时间点」与之对应「渲染的时间点」近似相同。所以 FMP 的时间点为「DOM 结构变化最剧烈的时间点」。「DOM 结构变化的时间点」可以利用 MutationObserver API 来获得。
- 通过 MutationObserver 监听每一次页面整体的 DOM 变化,触发 MutationObserver 的回调。
- 在回调计算出当前 DOM 树的分数,分数变化最剧烈的时刻,即为 FMP 的时间点。
算法的实现可参考《fmp-timing》,《如何相对准确的计算 FMP》,《指标搜集》等搜索结果。
SI(Speed Index)
衡量页面可视区域加载速度,帮助检测页面的加载体验差异。A和B的首次内容出现和完全加载时间是一样的,但是从用户角度A的体验明显更好。
TTI(Time to Interactive)
测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间。TTI 值越小,代表用户可以更早地操作页面,用户体验就更好。
FID(First Input Delay)
源自Event timing标准,深入了解由用户交互触发的事件的延迟。通常情况下,Input Delay 是因为浏览器主线程在忙于执行其他操作,无暇处理用户的交互操作。
FID 会测量从用户第一次与页面交互(比如当他们单击链接、点按按钮等等)直到浏览器对交互作出响应,实际能够开始处理事件、处理程序所经过的时间。
- FID 反映用户对页面交互性和响应性的第一印象,良好的第一印象有助于用户建立对整个应用的良好印象。
- 页面加载阶段,资源的处理任务最重,也最容易产生输入延迟。因此关注 FID 指标对于提升页面的可交互性有很大收益。
- FID 和页面加载完成后的 Input Delay 具有不同的解决方案。针对 FID,我们一般建议通过 Code Splitting 等方式减少页面加载阶段 JS 的加载、解析和执行时间。而页面加载完成后的 Input Delay,通常是由于开发人员代码编写不当、引起 JS 执行时间过长而产生的。
三个全新的性能指标,它们填补了用户体验故事中的空白。分别是:
LCP(Largest Contentful Paint)
最大的内容在可视区域内变得可见的时间点。最大的元素,例如一篇文章中的一大段文字或产品页面上的一张图片,大概就是让你理解页面内容的最有用的元素。
LCP容易理解,给出与FMP相似的结果,容易计算和上报。
指标 |
定义 |
存在的问题 |
FCP |
首次内容绘制时间 |
通常与用户无关 |
FMP |
首次绘制有意义内容的时间点 |
非标准化并且难以在浏览器之间统一实现 约 20% 的情况下不准确 |
SI |
跟踪在视口中加载内容的视觉进程 |
复杂的指标,难以解释 计算密集,不可用于线上监控 |
TBT(Total Blocking Time)
量化主线程在空闲之前的繁忙程度,有助于理解在加载期间,页面无法响应用户输入的时间有多久。
长任务:如果一个任务在主线程上运行超过 50 毫秒,那么它就是长任务。超过 50ms 后的任务耗时,都算作任务的阻塞时间。
一个页面的TBT,是从 FCP 到 TTI之间所有长任务的阻塞时间的总和。
TTI 有时可能会误导用户,但当与 TBT 结合使用时,你就会更清楚地了解页面对用户输入的响应程度。
CLS(Cumulative Layout Shift)
量化了在页面加载期间,视口中元素的移动程度。
当我们点击按钮时,突然出现了一块内容。无论是以一种增加意外点击几率的方式加载广告,还是在加载图片时文本向下移动,内容的意外移动都会让人非常不舒服。
CLS分数越低越好,因为这意味着在整个页面交互过程中发生的内容的偏移较少。
单次布局偏移的计算公式:score = 距离系数 * 影响分数
例如:
- 元素向下移动了视口高度的 ⅓,所以距离系数是 0.33。
- 元素在其起始位置和移动后的位置所占的面积占视口总面积的 ⅔,因此影响分数为 0.66。
- 布局偏移得分为 0.33 × 0.66 = 0.2178。
CLS的计算细节和原理可以查看 web.dev讲述累积布局偏移 (CLS)。
web-vitals 库提供了 LCP、FID、CLS、FCP 和 TTFB 指标。在 DevTools 中还能使用 Lighthouse 得到这些指标。
定义指标阈值
通常选择样本量的第 75 个百分位数来设置阈值,基于以下两个标准:
- 确保对页面或网站的大多数访问都达到了目标性能水平。
- 不受到异常值的过度影响。
关键指标的基准线
Metric Name |
Good(ms) |
Needs Improvement(ms) |
Poor(ms) |
FP |
0-1000 |
1000-2500 |
Over 2500 |
FCP |
0-1800 |
1800-3000 |
Over 3000 |
LCP |
0-2500 |
2500-4000 |
Over 4000 |
TTI |
0-3800 |
3800-7300 |
Over 7300 |
FID |
0-100 |
100-300 |
Over 300 |
CLS |
0-0.1(无单位) |
0.1-0.25(无单位) |
Over 0.25(无单位) |
这里为什么没有FMP、TBT 和 SI 呢?
经过测试,LCP 非常近似于FMP的时间点,FMP渐渐可以通过LCP代替。
SI的计算逻辑比较复杂,更常用在lighthouse中,而非线上监控。
虽然 TBT 可以在线上进行测量,但不建议这样做,因为用户交互会影响网页的 TBT,从而导致报告中出现大量差异,线上监控推荐使用 FID。
站点性能满意度计算
参考lighthouse的同时,去掉了仅实验室环境推荐测量的指标。
三、优化性能指标
网络优化
1. 开启 HTTP/2 ,关注兼容性问题,同时做好域名收敛
2. 开启brotli压缩,相比 gzip,它具有更高的压缩比和更快的压缩性能
3. 善用HTTPS,通过有效的优化手段,如Session Resume、OCSP Stapling等等,提升HTTPS性能
4. 使用CDN部署静态资源,有效降低访问延迟,提高可用性
5. DNS预解析,常用于CDN域名场景,减少DNS耗时
6. 提前建立网络连接,常用于Server API等域名,兼容性更好
缓存优化
资源加载优化
从请求时机、文件体积、加载方式等等方向优化
四、优化用户指标
优化 FP && FCP
尽快渲染,加载快、解析快、渲染快,最终的值才会越优秀
- 消除阻塞渲染的资源
- 缩小 CSS && 移除未使用的 CSS
- 预连接到所需的来源
- 减少服务器响应时间 (TTFB)
- 避免多个页面重定向
- 预加载关键请求
- 避免巨大的网络负载
- 使用高效的缓存策略服务静态资产
- 避免 DOM 过大
- 最小化关键请求深度
- 确保文本在网页字体加载期间保持可见
- 保持较低的请求数和较小的传输大小
优化 FMP && LCP
缩短页面关键路径的渲染时间,主要受四个因素的影响:
优化 FID
如何更快地响应用户交互
优化 CLS
尽量减少布局偏移,CLS较差的常见原因:
- 无尺寸的图像:设置长宽、或者通过使用CSS 宽比容器预留所需的空间。
- 无尺寸的广告、嵌入和 iframe:预留空间、避免在可视区域顶部放置广告、使用占位符或者预先计算足够的空间。
- 动态注入的内容:预留空间,比如使用占位符或者骨架屏等。
- 导致不可见文本闪烁 (FOIT)/无样式文本闪烁 (FOUT) 的网络字体:预加载字体。
- 在更新 DOM 之前等待网络响应的操作:倾向于选择transform动画,而不是触发布局偏移的属性动画(CSS 触发器和高性能动画)。
优化TTI
尽快的渲染、尽早的请求、请求尽快结束、尽量避免长任务。
- 参考如何优化FCP
- 预加载关键请求
- 最小化关键请求深度
- 减少JS执行时间
- 最小化主线程工作
- 保持较低的请求数和传输大小
参考: