衡量关键渲染路径

Ilya Grigorik
Ilya Grigorik

发布时间:2014 年 3 月 31 日

作为每个可靠性能策略的基础,准确的评估和检测必不可少。无法评估就谈不上优化。本指南介绍了评估 CRP 性能的不同方法。

  • Lighthouse 方法会对页面运行一系列自动化测试,然后生成关于页面的 CRP 性能的报告。此方法对您的浏览器中加载的特定页面的 CRP 性能提供了快速且基本的高级概览,让您可以快速地测试、循环访问和提高其性能。
  • Navigation Timing API 方法可捕获真实用户监控 (RUM) 指标。如名称所示,这些指标捕获自真实用户与网站的互动,并为真实的 CRP 性能(您的用户在各种设备和网络状况下的体验)提供了准确的信息。

通常情况下,最好利用 Lighthouse 发现明显的 CRP 优化机会,然后使用 Navigation Timing API 设置您的代码,以便监控应用在实际使用过程中的性能。

Lighthouse 是一款 Web 应用审核工具,可对给定页面运行一系列测试,然后在汇总报告中显示该页面的结果。您可以将 Lighthouse 作为 Chrome 扩展程序或 NPM 模块运行,这对将 Lighthouse 与持续集成系统集成非常有用。

请阅读使用 Lighthouse 审核网络应用,开始使用 Lighthouse。

当您将 Lighthouse 作为 Chrome 扩展程序运行时,您网页的 CRP 结果将如以下屏幕截图所示。

Lighthouse 的 CRP 审核

如需详细了解此审核的结果,请参阅关键请求链

结合使用 Navigation Timing API 和页面加载时发出的其他浏览器事件,您可以捕获并记录任何页面的真实 CRP 性能。

Navigation Timing

上图中的每一个标签都对应着浏览器为其加载的每个网页追踪的细粒度时间戳。实际上,在这个具体例子中,我们展示的只是各种不同时间戳的一部分。我们暂且跳过所有与网络有关的时间戳,但在后面的课程中还会做详细介绍。

那么,这些时间戳有什么含义呢?

  • domLoading:这是整个进程的开始时间戳,浏览器即将开始解析 HTML 文档中第一个收到的字节。
  • domInteractive:表示浏览器完成对所有 HTML 的解析并且 DOM 构建完成的时间点。
  • domContentLoaded:表示 DOM 准备就绪并且没有样式表阻止 JavaScript 执行的时间点,这意味着现在我们可以构建渲染树了。
    • 许多 JavaScript 框架都会等待此事件发生后,才开始执行它们自己的逻辑。因此,浏览器会捕获 EventStartEventEnd 时间戳,让我们能够追踪执行所花费的时间。
  • domComplete:顾名思义,所有处理完成,并且网页上的所有资源(图像等)都已下载完毕,也就是说,加载转环已停止旋转。
  • loadEvent:作为每个网页加载的最后一步,浏览器会触发 onload 事件,以便触发额外的应用逻辑。

HTML 规范中规定了每个事件的具体条件:应在何时触发、应满足什么条件以及其他重要注意事项。为此,我们将重点介绍与关键渲染路径相关的几个关键里程碑:

  • domInteractive 表示 DOM 准备就绪的时间点。
  • domContentLoaded 通常用于标记 DOM 和 CSSOM 均准备就绪的时间。
    • 如果没有阻塞解析器的 JavaScript,则 DOMContentLoaded 将在 domInteractive 后立即触发。
  • domComplete 表示网页及其所有子资源都准备就绪的时间点。
<!DOCTYPE html>
<html>
  <head>
    <title>Critical Path: Measure</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link href="style.css" rel="stylesheet" />
    <script>
      function measureCRP() {
        var t = window.performance.timing,
          interactive = t.domInteractive - t.domLoading,
          dcl = t.domContentLoadedEventStart - t.domLoading,
          complete = t.domComplete - t.domLoading;
        var stats = document.createElement('p');
        stats.textContent =
          'interactive: ' +
          interactive +
          'ms, ' +
          'dcl: ' +
          dcl +
          'ms, complete: ' +
          complete +
          'ms';
        document.body.appendChild(stats);
      }
    </script>
  </head>
  <body onload="measureCRP()">
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg" /></div>
  </body>
</html>

试试看

上面的示例乍一看可能有点晕,但实际上的确相当简单。Navigation Timing API 会捕获所有相关时间戳,而我们的代码会等待 onload 事件触发(回想一下,onload 事件在 domInteractivedomContentLoadeddomComplete 之后触发),然后计算各个时间戳之间的间隔。

NavTiming 演示

完成了所有这一切,现在,我们有一些需要跟踪的特定里程碑,以及一个用于输出这些测量结果的基本功能。请注意,您也可以修改代码,以将这些指标发送到分析服务器(Google Analytics 会自动执行此操作),而不是在网页上输出这些指标。这非常有助于您跟踪网页的效果,并确定可以通过优化工作获益的候选网页。

DevTools 怎么样?

尽管本文档使用 Chrome DevTools 的 Network 面板说明 CRP 概念,但 DevTools 并不适合 CRP 评估,因为它没有隔离关键资源的内置机制。运行 Lighthouse 审核以帮助识别此类资源。

反馈