推迟非关键 CSS

Demián Renzulli
Demián Renzulli

CSS 文件是会阻塞渲染的资源:必须先加载并处理这些文件,浏览器才能渲染网页。包含过大的样式表的网页需要更长时间才能呈现。

了解如何延迟加载非关键 CSS,以优化关键渲染路径并改善首次内容绘制 (FCP)

CSS 加载欠佳

以下示例包含一个手风琴,其中包含三个隐藏的文本段落,每个段落都使用不同的类设置了样式:

此网页请求了一个包含 8 个类的 CSS 文件,但并非所有类都是呈现“可见”内容所必需的。

本指南的目标是优化此网页,以便仅同步加载关键样式,而其余样式(包括段落样式)则以非阻塞方式加载。

测量

在开发者工具中运行 Lighthouse,以查看有影响的指标。

  1. 在 Chrome 中打开演示
  2. 打开 Chrome 开发者工具
  3. 选择“效果”面板
  4. 在面板内,重新加载页面。

报告显示 First Contentful Paint 指标的值为“1 秒”,并显示消除会阻塞渲染的资源机会,指向 style.css 文件:

未优化网页的 Lighthouse 报告,显示“首次内容绘制时间”为“1 秒”,并且“机会”下显示“消除阻塞渲染的资源”
Lighthouse 报告建议简化样式表,以加快网页加载速度。

在生成的轨迹中,FCP 标记放置在 CSS 完成加载后:

未优化的网页的开发者工具性能轨迹,显示 FCP 在 CSS 加载后开始。
在未优化的演示网页上,只有在 CSS 完成加载后,才会发生 FCP。

这意味着浏览器需要等待所有 CSS 加载并处理完毕,然后才能在屏幕上绘制单个像素。

优化

如需优化此网页,请使用覆盖率工具确定哪些类被视为关键

  1. Control+Shift+PCommand+Shift+P (Mac) 打开 DevTools 命令菜单
  2. 输入“覆盖面”,然后选择显示覆盖面
  3. 点击重新加载即可重新加载页面并开始捕获覆盖率。
CSS 文件的覆盖率,显示了 55.9% 的未用字节。
覆盖率报告显示了在初始网页加载时实际使用了多少 CSS。

双击报告即可查看详细信息:

  • 以绿色标记的类是关键类。浏览器需要这些信息来呈现可见内容,包括标题、副标题和手风琴按钮。
  • 以红色标记的类是非关键类,仅影响非立即显示的内容,例如隐藏的段落。

根据此信息,优化您的 CSS,以便浏览器可以在网页加载后立即开始处理关键样式,并将非关键 CSS 延迟到稍后处理:

  1. 提取覆盖率报告中标记为绿色的类定义,并将这些类放在网页开头的 <style> 代码块中:

    <style type="text/css">
    .accordion-btn {background-color: #ADD8E6;color: #444;cursor: pointer;padding: 18px;width: 100%;border: none;text-align: left;outline: none;font-size: 15px;transition: 0.4s;}.container {padding: 0 18px;display: none;background-color: white;overflow: hidden;}h1 {word-spacing: 5px;color: blue;font-weight: bold;text-align: center;}
    </style>
    
  2. 通过应用以下模式异步加载其余类:

    <link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link rel="stylesheet" href="styles.css"></noscript>
    

这不是加载 CSS 的标准方式。具体操作过程如下:

  • link rel="preload" as="style" 异步请求样式表。如需详细了解 preload,请参阅预加载关键素材资源指南
  • link 中的 onload 属性可让浏览器在样式表加载完毕后处理 CSS。
  • onload 处理程序使用完毕后将其设为“null”,有助于某些浏览器在切换 rel 属性时避免重新调用该处理程序。
  • noscript 元素内对样式表的引用为不执行 JavaScript 的浏览器提供了一种回退机制。

正式版

在生产环境中,我们建议使用 CSS 延迟函数(例如 loadCSS),这些函数可封装此行为,并在各种浏览器中正常运行。这些函数支持内容安全政策,该政策可能不允许内嵌 onload JavaScript。

您还可以将 CSS 链接放置在网页底部,这样内容就可以在浏览器中呈现,而无需等待样式表加载。 不过,浏览器仍会优先处理样式表,因此仍可能会阻止浏览器中的关键内容。

即使大多数样式以异步方式加载,生成的网页也与之前的版本完全相同。

监控

使用开发者工具对优化后的网页运行另一项性能轨迹分析。

FCP 标记出现在网页请求 CSS 之前,这意味着浏览器无需等待 CSS 加载完成即可呈现网页:

优化后的网页的开发者工具性能轨迹,显示 FCP 在 CSS 加载之前开始。
在优化后的网页上,FCP 可以在样式表加载之前开始。

最后一步是对优化后的网页运行 Lighthouse。

在报告中,您会看到 FCP 页面缩短了 0.2 秒(性能提升了 20%!):

Lighthouse 报告,显示 FCP 值为“0.8 秒”。

移除阻塞渲染的资源建议不再显示在机会下,而是显示在通过的审核部分中:

Lighthouse 报告的图示,显示了“通过的审核”部分中的“消除会阻塞渲染的资源”。
该网页现在通过了阻塞资源审核。

后续步骤和参考资料

对于更复杂的生产环境,提取关键 CSS 指南介绍了用于提取关键 CSS 的一些最热门的工具,并包含一个 Codelab,用于演示这些工具在实践中的运作方式。