阻塞渲染的 CSS

Ilya Grigorik
Ilya Grigorik

发布时间:2014 年 3 月 31 日

默认情况下,CSS 被视为阻塞渲染的资源,这意味着 浏览器不会渲染任何已处理的内容,除非 CSSOM 结构。请务必精简您的 CSS,尽快提供它,并利用媒体类型和查询来解除对渲染的阻塞。

渲染树构建中,我们看到关键渲染路径需要 DOM 和 CSSOM 才能构建渲染树。这会给性能造成严重影响:HTML 和 CSS 都是阻塞渲染的资源。HTML 是显而易见的,因为如果没有 DOM,我们就无法呈现任何内容,但 CSS 要求可能不那么明显。如果我们尝试在 CSS 上不阻塞渲染的情况下渲染典型的网页,会发生什么情况?

摘要

  • 默认情况下,CSS 被视为阻塞渲染的资源。
  • 我们可以通过媒体类型和媒体查询将一些 CSS 资源标记为不阻塞渲染。
  • 浏览器会下载所有 CSS 资源,无论阻塞还是不阻塞。
<ph type="x-smartling-placeholder">
</ph> 使用 CSS 的纽约时报
《纽约时报》与 CSS 合作
<ph type="x-smartling-placeholder">
</ph> 不使用 CSS 的 NYTimes
不使用 CSS 的纽约时报 (FOUC)

前面的例子是《纽约时报》网站使用和不使用 CSS 的对比,说明了为何要在 CSS 可用之前阻塞渲染,而不使用 CSS,网页就相对无法使用。右侧的情况通常称为内容样式短暂失效 (FOUC)。浏览器将阻塞渲染,直至 DOM 和 CSSOM 全都准备就绪。

CSS 是一种阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。

不过,如果我们有一些 CSS 样式只在特定条件下(例如显示网页或将网页投影到大型显示器上时)使用,又该如何?如果这些资源不阻塞渲染,该有多好。

CSS“媒体类型”和“媒体查询”使我们能够应对以下用例:

<link href="style.css" rel="stylesheet" />
<link href="print.css" rel="stylesheet" media="print" />
<link href="other.css" rel="stylesheet" media="(min-width: 40em)" />

媒体查询由一种媒体类型以及零个或多个用于检查特定媒体功能状况的表达式组成。例如,上面的第一个样式表声明未提供任何媒体类型或查询,因此它适用于所有情况,也就是说,它始终会阻塞渲染。另一方面,第二个样式表声明仅在打印内容时适用 - 您可能想要重新排列布局、更改字体以及其他有关打印的重要设计注意事项。因此,在网页首次加载时,此样式表声明不需要阻止网页的渲染。最后,最后一个样式表声明提供了“媒体查询”由浏览器执行:如果条件匹配,浏览器将阻止呈现,直到样式表下载和处理为止。

通过使用媒体查询,我们可以根据特定用例(例如显示与打印)以及动态条件(例如屏幕方向变化、调整大小事件等)来定制呈现方式。声明样式表资产时,请密切注意媒体类型和查询,因为它们将严重影响关键渲染路径的性能。

请考虑以下示例:

<link href="style.css" rel="stylesheet" />
<link href="style.css" rel="stylesheet" media="all" />
<link href="portrait.css" rel="stylesheet" media="orientation:portrait" />
<link href="print.css" rel="stylesheet" media="print" />
  • 第一个声明是阻塞渲染,在所有条件下都匹配。
  • 第二个声明同样会阻塞渲染:"all" 是默认类型,如果您不指定类型,则系统会隐式将其设置为 "all"。因此,第一个声明和第二个声明实际上是等效的。
  • 第三个声明具有动态媒体查询,将在网页加载时计算。根据网页加载时设备的方向,portrait.css 可能阻塞渲染,也可能不阻塞渲染。
  • 最后一个声明仅在打印网页 ("print") 时应用,因此当网页首次在浏览器中加载时,它不会阻塞渲染。

最后,请注意“阻塞渲染”仅是指浏览器是否需要暂停网页的首次渲染,直至该资源准备就绪。无论是哪种情况,浏览器仍会下载 CSS 资源,只不过非阻塞资源的优先级较低。

反馈