使用 Critical 提取并内嵌关键 CSS

Milica Mihajlija
Milica Mihajlija

无论您是使用界面库还是自行设计样式,交付大量 CSS 都会延迟渲染,因为浏览器必须先下载并解析 CSS 文件,然后才能显示网页。

此自适应冰淇淋图库是使用 Bootstrap 构建的。Bootstrap 等界面库可以加快开发速度,但通常会导致 CSS 过于庞大且不必要,从而减慢加载时间。Bootstrap 4 为 187 KB,而另一个界面库 Semantic UI 在未压缩的情况下竟然高达 730 KB。即使经过缩减和 Gzip 压缩,Bootstrap 的大小仍约为 20 KB,远远超过首次往返的 14 KB 阈值

Critical 是一款用于提取、缩减和内嵌首屏 CSS 的工具。这样一来,即使页面其他部分的 CSS 尚未加载,也能尽快渲染上翻区内容。在此 Codelab 中,您将学习如何使用 Critical 的 npm 模块。

测量

  • 如需预览网站,请按 View App(查看应用)。然后按 Fullscreen(全屏)全屏

如需在此网站上运行 Lighthouse 审查,请执行以下操作:

  1. 按 `Control+Shift+J`(在 Mac 上为 `Command+Option+J`)打开 DevTools。
  2. 点击 Lighthouse 标签页。
  3. 点击移动
  4. 选中性能复选框。
  5. 清除“审核”部分中的其余复选框。
  6. 点击模拟快速 3G,CPU 降速 4 倍
  7. 选中清除存储空间复选框。选择此选项后,Lighthouse 将不会从缓存加载资源,从而模拟初次访问者对网页的体验。
  8. 点击运行审核

Chrome 开发者工具的 Audits 面板,由 Lighthouse 提供支持

在您的机器上运行审核时,具体结果可能会有所不同,但在影片片段视图中,您会发现应用会显示一段时间的空白屏幕,然后才会最终呈现内容。正因如此,First Contentful Paint (FCP) 表现较高,而总体性能得分却较低。

Lighthouse 审核结果显示性能得分为 84、FCP 为 3 秒以及应用加载时的幻灯影片视图

Lighthouse 可帮助您解决效果问题,因此请在优化部分查找解决方案。移除阻塞渲染的资源被列为一个机会,而 Critical 正是发挥作用的地方!

Lighthouse 审核的“优化建议”部分列出了“移除阻塞渲染的资源”

优化

  • 点击 Remix to Edit 即可修改项目。

为了加快速度,Codelab 中已安装 Critical,但此 Codelab 中包含一个空配置文件。

在配置文件 critical.js 中,添加对 Critical 的引用,然后调用 critical.generate() 函数。此函数接受包含配置的对象。

const critical = require('critical');

critical.generate({
    // configuration
},(err, output) => {
  if (err) {
    console.error(err);
  } else if (output) {
    console.log('Generated critical CSS');
  }
});

错误处理不是一项强制性要求,但您可以通过它在控制台中轻松衡量操作是否成功。

配置“关键”

下表包含一些有用的关键选项。您可以在 GitHub 上查看所有可用选项

选项 类型 说明
base 字符串 文件的基本目录。
src 字符串 HTML 源文件。
dest 字符串 输出文件的目标。如果内嵌了 CSS,则输出文件为 HTML。否则,输出为 CSS 文件。
widthheight 数字 视口宽度和高度(以像素为单位)。
dimensions 数组 包含具有宽度和高度属性的对象。这些对象代表您要使用上翻页 CSS 定位到的视口。如果您的 CSS 中有媒体查询,则可以生成涵盖多种视口尺寸的关键 CSS。
inline 布尔值 设置为 true 后,系统会将生成的关键 CSS 内嵌到 HTML 源文件中。
minify 布尔值 设置为 true 时,Critical 会缩减生成的关键 CSS。在为多种分辨率提取关键 CSS 时可以省略,因为 Critical 会自动缩减它以避免包含重复的规则。

以下是用于提取多种分辨率的关键 CSS 的配置示例。将其添加到 critical.js,或试着调整选项。

critical.generate({
  base: 'public/',
  src: './index.html',
  dest: './index.html',
  inline: true,
  dimensions: [
    {
      height: 500,
      width: 300,
    },
    {
      height: 720,
      width: 1280,
    },
  ]
}, (err, output) => {
  if (err) {
    console.error(err);
  } else if (output) {
    console.log('Generated critical CSS');
  }
});

在此示例中,index.html 既是源文件,也是目标文件,因为 inline 选项已设置为 true。“Essential”会先读取 HTML 源文件,提取关键 CSS,然后使用 <head> 中内嵌的关键 CSS 覆盖 index.html

dimensions 数组指定了两个视口大小:300 x 500(超小屏幕)和 1280 x 720(标准笔记本电脑屏幕)。

省略了 minify 选项,因为如果指定了多个视口尺寸,“严重”会自动缩减提取的 CSS。

运行严重

package.json 中为脚本添加“Critical”:

scripts: {
  "start": "node server.js",
  "critical": "node critical.js"
}
  1. 点击终端(注意:如果系统未显示“终端”按钮,您可能需要使用“全屏”选项)。

如需生成关键 CSS,请在控制台中运行以下命令:

npm run critical
refresh
控制台中显示“Generated critical CSS”(生成了关键 CSS)的成功消息
控制台中的成功消息

现在,在 index.html<head> 标记中,生成的关键 CSS 会内嵌在 <style> 标记之间,后跟一个用于异步加载其余 CSS 的脚本。

内嵌了关键 CSS 的 index.html
内嵌关键 CSS

再次测量

按照 Codelab 开头部分的步骤再次运行 Lighthouse 性能审核。您获得的结果将如下所示:

Lighthouse 审核结果,显示性能得分为 100、FCP 为 0.9 秒,以及应用加载的改进版影片片段视图