渐进式网页渲染指标
| 指标名 | 中文 | 全称 | 描述 |
|---|---|---|---|
| FP | 首次绘制 | First Paint | 标记浏览器渲染任何在视角上不同于导航前屏幕内容的时间点 |
| FCP | 首次内容绘制 | First Contentful Paint | 标记浏览器渲染来自DOM第一位内容的时间点 |
| FMP | 首次有效绘制 | First Meaningful Paint | 标记页面主要内容绘制的时间点(因为依赖算法猜测有效元素,所以目前基本被弃用) |
| LCP | 最大内容绘制 | Largest Contentful Paint | 标记在可视区“内容”最大的可见元素开始绘制在屏幕上的时间点 |
对于浏览器来说,白屏结束是从FCP开始,但是有可能只是渲染了一个边栏或者loading,所以“首屏时间”对于用户来说,应该是LCP的时间。 LCP的计算逻辑是浏览器给定的。所以浏览器认为的“最大的可见元素”也未必是我们业务中“真正重要的”内容,而且对于单页应用和通过hash路由驱动不同子应用加载的微服务应用来说,以上的指标都无法满足在主体框架加载完成后切换不同页面时的重新计算。 为了更准确了解页面的加载时间,我们用一个新的元素计时API:elementtiming;Chrome和Edge在新版本给予了支持。 Element Timing API 的目的是让 Web 开发人员或分析工具能够测量页面上关键元素的渲染时间,比起 LCP ,我们能够自己来定义关键元素,支持的元素有:
<img><svg>中的<img><video>中的poster image- 拥有background-image的元素
- 一组文本节点
- 必须是块级元素
- 直接子节点必须包含一个或多个文本节点(文本或者内联元素内有文本)
<img src="image.jpg" elementtiming="big-image">
<p elementtiming="text" id="text-id">text here</p>
const observer = new PerformanceObserver((list) => {
let entries = list.getEntries().forEach(function (entry) {
console.log(entry);
});
});
observer.observe({ entryTypes: ["element"] });
// 输出 entry 内容:
// {
// duration: 0
// element: p.aimake-site-name
// entryType: "element"
// id: ""
// identifier: "text-id"
// intersectionRect: DOMRectReadOnly {x: 236, y: 130, width: 144, height: 28, top: 130, …}
// loadTime: 0
// name: "text-paint"
// naturalHeight: 0
// naturalWidth: 0
// renderTime: 10850.899999976158
// startTime: 10850.899999976158
// url: ""
// }
在添加了自定义elementtiming属性后,元素在真正渲染时,浏览器就会记录时间,所以,我们可以在不同应用中,让开发人员直接给能够标志首屏的元素添加该属性,即可由采集脚本通过监听PerformanceObserver来统一采集到元素绘制的时间点了。通过使用Element Timing API,我们能够更精确地记录应用、页面甚至功能模块的加载时长。