推迟非关键 CSS

Demián Renzulli
Demián Renzulli

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

在本指南中,您将了解如何推迟非关键 CSS 来优化关键渲染路径并改进首次内容绘制 (FCP)

示例:次优 CSS 加载

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

此页面请求了包含 8 个类的 CSS 文件,但呈现“可见”内容并不需要全部类。

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

测量

页面上运行 Lighthouse,然后前往 Performance 部分。

该报告显示值为“1s”的 First Contentful Paint 指标,以及指向 style.css 文件的优化建议Eliminate render-blocking resources

未优化页面的 Lighthouse 报告,其中显示 FCP 为“1 秒”,“消除阻塞资源”在“优化建议”下显示
Lighthouse 报告建议您简化样式表,以便提高网页加载速度。

要直观呈现此 CSS 如何阻止呈现,请执行以下操作:

  1. 在 Chrome 中打开相应网页
  2. Control+Shift+J(在 Mac 上,按 Command+Option+J)即可打开开发者工具。
  3. 点击效果标签页。
  4. 在“性能”面板中,点击重新加载

在生成的轨迹中,您会看到 FCP 标记在 CSS 完成加载后立即放置:

开发者工具中未优化页面的性能跟踪记录,显示 CSS 加载后启动的 FCP。
在未优化的演示页面上,只有在 CSS 加载完毕后才能执行 FCP。

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

优化

为了优化此页面,您需要了解哪些类被视为关键。如需确定这一点,请使用覆盖率工具

  1. 在开发者工具中,按 Control+Shift+PCommand+Shift+P (Mac) 打开命令菜单
  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 文件的异步请求在 HTML 文件中如下所示:

监控

使用开发者工具在经过优化的页面上运行另一个性能跟踪记录。

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

开发者工具中已优化页面的性能跟踪记录,显示 FCP 在 CSS 加载之前启动。
在优化页面上,FCP 可以在样式表加载之前启动。

最后,在经过优化的页面上运行 Lighthouse。

在该报告中,您会看到 FCP 页面减少了 0.2 秒(提高了 20%!):

Lighthouse 报告,显示的 FCP 值为“0.8s”。
全新的更低 FCP。

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

Lighthouse 报告,在“已通过的审核”部分显示了“Eliminate block resources”(清除阻塞资源)。
该网页现在通过了屏蔽资源的审核。

后续步骤和参考文档

在本指南中,您学习了如何通过手动提取网页中未使用的代码来推迟非关键 CSS。对于更复杂的生产环境,请参阅提取关键 CSS 指南,其中介绍了一些用于提取关键 CSS 的最热门工具,并且还提供了 Codelab,以便了解这些工具的实际工作方式。