Chrome Devtool Performance中DCL, L, FP, FCP, FMP, LCP 的含义

13,911 阅读4分钟

Chrome Devtool Performance 是大家常用的页面性能分析工具,当你使用它来分析页面加载性能的时候会生成如下图所示的报告。

图中包含了以下几个重要的时间点:DCL, L, FP, FCP, FMP, LCP。这里我把前两个和后面几个分开来讲,因为它们分属于不同的W3C标准/草案:navigation timingPaint timing

DCL, L

DCL(DOMContentLoaded) 表示HTML加载完成事件, L(onLoad) 表示页面所有资源加载完成事件,大家应该对这两个事件非常熟悉了,这里不再多介绍。

不仅是在 performance 报告中,在 Network 面板中也可以查看。

但 DCL 和 L 在 Performance 和 Network 中展示的值是不同的,这是因为 Performance 中时间线的起点是你点击录制按钮的时间,而 Network 中时间线的起点是 fetchStart 事件。fetchStart 又是什么呢?

Navigation Timing API

W3C性能工作组在 Navigation Timing API 中定义了一系列页面事件,其中便包括 fetchStart, DOMContentLoaded, Load等事件。

下图展示了从浏览器卸载旧页面到新页面加载完成的整个过程,每个页面事件穿插在每个页面加载阶段之间。

我们可以如下图通过window.performance.timing属性获取这些事件的具体时间戳,进而对页面性能进行分析。

然而 Navigation Timing API 中的 Load 和 DOMContentLoaded 等事件并不能真正的体现页面加载的性能,因为它们并不是与用户在屏幕上看到的相对应。幸运的是,以 Chrome 为首的浏览器提出了其他更能代表用户体验的性能指标。

FP, FCP, FMP, LCP

google工程师一直在推动以用户为中心的性能指标,这些指标旨在回答用户体验的三个问题:

1.发生了吗?
2.它有用吗?
3.它可以使用吗?

发生了吗?-- FP & FCP

当页面开始加载后,用户的第一个重要的体验便是这个。

FP(First Paint): 页面在导航后首次呈现出不同于导航前内容的时间点。

FCP(First Contentful Paint): 首次绘制任何文本,图像,非空白canvas或SVG的时间点。

FP和FCP可能是相同的时间,也可能FP先于FCP。下图展示了 FP 和 FCP 的区别。

这两个事件定义在 W3C Paint Timing 草案中,我们可以通过 window.performance.getEntriesByType('paint') 获取两个时间点的值。

它有用吗 -- FMP & LCP

FMP(First Meaningful Paint): 首次绘制页面“主要内容”的时间点。

FMP是由 Google 工程师引入的一种现代性能指标,它告诉我们页面何时‘有用’。其本质上是通过一种算法来猜测某个时间点可能是FMP。

Chrome目前并没有公开获取 FMP 的 API,只能通过 performance 或者 lighthouse 等性能测试工具查看。

LCP(Largest Contentful Paint): 可视区域“内容”最大的可见元素开始出现在页面上的时间点。

FMP的算法非常复杂,而且并不精确,Google 工程师研究发现了另一种能更精确更简单的测量页面何时“有用”的方法,那就是查看页面何时渲染最大的元素。

LCP目前是由 WICG(W3C Web平台孵化器社区组)提出的一项新特性,目前还不是W3C正式规范。我们可以通过 Chrome 的 PerformanceObserver API 计算它。

// Create a variable to hold the latest LCP value (since it can change).
let lcp;

// Create the PerformanceObserver instance.
const po = new PerformanceObserver((entryList) => {
  const entries = entryList.getEntries();
  const lastEntry = entries[entries.length - 1];

  // Update `lcp` to the latest value, using `renderTime` if it's available,
  // otherwise using `loadTime`. (Note: `renderTime` may not be available if
  // the element is an image and it's loaded cross-origin without the
  // `Timing-Allow-Origin` header.)
  lcp = lastEntry.renderTime || lastEntry.loadTime;
});

// Observe entries of type `largest-contentful-paint`, including buffered
// entries, i.e. entries that occurred before calling `observe()`.
po.observe({type: 'largest-contentful-paint', buffered: true});

// Send the latest LCP value to your analytics server once the user
// leaves the tab.
addEventListener('visibilitychange', function fn() {
  if (lcp && document.visibilityState === 'hidden') {
    console.log('LCP:', lcp);
    removeEventListener('visibilitychange', fn, true);
  }
}, true);

用户体验的第三个问题“可以使用吗”可以用 TTI(Time to Interactive) 查看,它表示你的页面何时可以自由响应用户交互。它和 FMP 一样还不是 W3C 规范,也没有获取它的标准的 API,但 Google 提供了一个 TTI 的 polyfill 可以用来检测,你也可以用 lighthouse 获取 TTI。

新的性能指标

在今年11月举行的 Chrome Developer Summit 上,W3C 性能工作组介绍了他们正在研究的三个性能指标:LCP, CLSTBT

CLS(Cumulative Layout Shift): 表示用户经历的意外 layout 偏移的频率。

TBT(Total Blocking Time): 表示从 FCP 到 TTI 之间,所有 long task 的阻塞时间之和。

新的 Lighthouse 性能得分将很快不再强调 FMP 和 FCI,并将包含 LCP, TBT, CLS 三个新特性。