推迟非关键 CSS

CSS 文件是 渲染阻塞资源:它们必须在浏览器渲染页面之前加载和处理。包含不必要的大型样式表的网页需要更长时间才能渲染。

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

示例:次优 CSS 加载

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

此页面请求一个包含八个类的 CSS 文件,但并非所有类都是渲染“可见”内容所必需的。

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

测量

此页面 上运行 Lighthouse,然后导航到“性能”部分。

报告显示“首次内容绘制”指标的值为“1 秒”,以及“消除渲染阻塞资源”机会,指向 style.css 文件

Lighthouse
    report for unoptimized page, showing FCP of '1s' and 'Eliminate blocking
    resources' under 'Opportunities'
Lighthouse 报告建议简化样式表,以加快页面加载速度。

要可视化此 CSS 如何阻塞渲染

  1. 在 Chrome 中打开 此页面
  2. Control+Shift+J(或 Mac 上的 Command+Option+J)打开 DevTools。
  3. 点击“性能”选项卡。
  4. 在“性能”面板中,点击“重新加载”。

在生成的跟踪记录中,您将看到“FCP”标记放置在 CSS 完成加载后

DevTools performance trace for unoptimized page, showing FCP starting after CSS loads.
在未优化的演示页面上,FCP 必须在 CSS 完成加载后才能发生。

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

优化

要优化此页面,您需要知道哪些类被认为是关键的。要确定这一点,请使用 Coverage 工具

  1. 在 DevTools 中,按 Control+Shift+PCommand+Shift+P (Mac) 打开 命令菜单
  2. 输入“Coverage”,然后选择“显示 Coverage”。
  3. 点击“重新加载”以重新加载页面并开始捕获 Coverage。
Coverage for CSS file, showing 55.9% unused bytes.
Coverage 报告显示了在初始页面加载中实际使用了多少 CSS。

双击报告以查看详细信息

  • 绿色标记的类是关键的。浏览器需要它们来渲染可见内容,包括标题、副标题和手风琴按钮。
  • 红色标记的类是非关键的,仅影响非立即可见的内容,例如隐藏的段落。

有了这些信息,优化您的 CSS,以便浏览器可以在页面加载后立即开始处理关键样式,并将非关键 CSS 推迟到稍后处理

  1. 提取 Coverage 报告中标记为绿色的类定义,并将这些类放在页面头部的 <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 处理程序在使用后,有助于某些浏览器避免在切换 rel 属性时重新调用处理程序。
  • noscript 元素内的样式表引用为不执行 JavaScript 的浏览器提供了后备方案。

结果页面看起来与之前的版本完全相同,即使大多数样式都是异步加载的。以下是在 HTML 文件中内联样式和对 CSS 文件的异步请求的外观

监控

使用 DevTools 在 优化后的页面 上运行另一个“性能”跟踪。

FCP”标记出现在页面请求 CSS 之前,这意味着浏览器无需等待 CSS 加载即可渲染页面

DevTools
    performance trace for optimized page, showing FCP starting before CSS
    loads.
在优化后的页面上,FCP 可以在样式表加载之前开始。

作为最后一步,在优化后的页面上运行 Lighthouse。

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

Lighthouse report, showing an FCP value of '0.8s'.
新的、减少的 FCP。

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

A depiction
    of Lighthouse report, showing 'Eliminate blocking resources' on the 'Passed
    Audits' section.
页面现在通过了阻塞资源审核。

后续步骤和参考资料

在本指南中,您学习了如何通过手动提取页面中未使用的代码来推迟非关键 CSS。对于更复杂的生产环境,提取关键 CSS 指南涵盖了一些最流行的提取关键 CSS 的工具,并包含 一个 Codelab,以了解它们在实践中的工作方式