[译]使用 CSS 提升页面渲染速度

Image by Arek Socha from Pixabay

用户喜欢流畅的 Web 应用体验。他们希望页面可以快速加载并且平稳运行。如果用户在浏览网站过程中出现断断续续的动画或延迟,那么他们极有可能离开该网站。作为开发人员,你可以在改善用户体验上做很多事情。本文将重点介绍 4 个可以提升页面渲染速度的 CSS 技巧。

1. Content-visibility

一般来说,大多数 Web 应用都有复杂的 UI 元素,其关联的内容超出了用户在浏览器视图中的可视范围。这种情况下,我们可以设置 content-visibility 属性来跳过对屏幕以外内容的渲染。如果有大量屏幕以外内容,这将大大减少页面渲染时间。

这是最新添加的特性之一,它是提高渲染性能最具影响力的特性之一。 content-visibility 接收多个值,我们可以在一个元素上使用 content-visibility: auto; 立即获得性能提升。

让我们观察下面这个页面,它包含了多个不同信息的卡片。虽然屏幕可以显示大约 12 张卡片,但列表中大约有 375 张卡片。如你所见,浏览器用了 1037ms 来加载这个页面。

Regular HTML page
Regular HTML page

接下来,你可以给所有卡片添加 content-visibility 属性。

在这个例子中,在页面添加了 content-visibility 后,渲染时间下降到了 150ms。性能提升了 6 倍多

With content-visibility
With content-visibility

正如你所见,content-visibility 属性非常强大,对于改善页面加载时间非常有用。到目前为止,根据我们讨论的内容,你一定认为它是提升页面渲染速度的灵丹妙药。

content-visibility 的局限性

然而,content-visibility 也有其不适合使用的场景。我想强调两点供你考虑。

  • 该特性仍处于实验阶段
    到目前为止,火狐(PC 和安卓版本),IE(我认为他们并不计划把这个特性添加到 IE 中) 和 Safari (Mac 和 iOS)都不支持 content-visibility 属性。
  • 滚动条相关的异常问题.
    因为页面元素最初呈现的高度是 0px,所以当向下滚动时,这些元素就会出现在屏幕上。实际内容将被渲染,元素的高度也将相应地更新。这将使滚动条出现异常行为。
Scroll behavior with content-visibility
Scroll behavior with content-visibility

为了解决滚动条的问题,你可以使用另一个 CSS 属性 container-intrinsic-size。它可以指定一个元素的原始大小。因此元素将以指定的高度渲染,而不是以 0px。

.element{
    content-visibility: auto;
    contain-intrinsic-size200px;
}

然而,在实践过程中,我发现如果有大量的元素将 content-visibility 设置为 auto ,即使使用 container-intrinsic-size,依然存在滚动条相关的小问题。

因此,我的建议是规划好页面布局,将其分解为多个模块,然后在这些模块上使用 content-visibility,从而使得滚动条行为正常。

2. Will-change 属性

浏览器上的使用动画已经不是新鲜事了。通常,浏览器会按照一定规律渲染这些动画和其他页面元素。但是,现在可以使用 GPU 来优化其中的某些动画操作。

使用 CSS 的 will-change 属性,我们可以指定该元素修改特定属性,从而使浏览器执行前进行必要性能的优化。

其底层原理是浏览器为指定 will-change 属性的元素创建一个单独的层级。接着,它将元素的渲染和其他优化委托给 GPU。GPU 将加速接管动画的渲染,从而使得动画更加流畅。

考虑以下 CSS:

// stylesheet 文件
.animating-element {
  will-change: opacity;
}

// HTML 文件

<div class="animating-elememt">
  Animating Child elements
</div>

在浏览器中渲染以上代码片段时,它将识别出 will-change 属性,并在之后的渲染中优化与透明度相关的更改。

根据 Maximillian Laumeister 所做的性能基准测试,你可以看到,通过这一行修改,使得该元素获得了超过 120 帧/秒的渲染速度,最初大约是 50 帧/秒。

Without using will-change; Image by Maximilian
Without using will-change; Image by Maximilian
With will-change; Image by Maximilian
With will-change; Image by Maximilian

will-change 不适宜使用的场景

尽管 will-change 旨在提高渲染性能,但是如果你滥用它,也会导致 Web 应用性能的降低。

  • 使用 will-change 表示该元素将来会发生改变。
    所以如果你试图将 will-change 和动画同时使用,这将不会带来任何优化。因此,建议在父元素上使用 will-change 属性,在子元素上使用动画。
.my-class{
  will-change: opacity;
}

.child-class{
  transition: opacity 1s ease-in-out;
}
  • 请不要在与动画无关的元素上使用。
    在元素上使用 will-change 属性时,浏览器会将该元素转移到新的层级并转交给 GPU 对其进行优化。如果没有任何会发生改变的内容,将会导致资源浪费。

最后,需要牢记的一点是:建议在完成所有动画后,从元素中移除 will-change 属性。

3. 减少渲染阻塞时间

如今,许多 Web 应用程序必须适配多种机型的浏览器,包括 PC,平板和手机等。要实现响应式布局,我们必须根据不同的媒体尺寸编写不同的样式。涉及到页面渲染时,在 CSS 对象模型(CSSOM)准备就绪前,浏览器无法启动渲染。
根据你的 Web 应用程序,你可能会拥有一个比较大的样式表,以适应所有设备的外形尺寸。

但是,假设我们根据页面加载优先级将其拆分为多个样式表。在这种情况下,我们可以只让主要的 CSS 文件阻塞关键路径,并将其作为高优先级下载,而让其他样式表以较低优先级下载。

<link rel="stylesheet" href="styles.css">
Single stylesheet
Single stylesheet

拆分成多个样式表后:

<!-- style.css 只包含渲染页面所需的最少样式表 -->
<link rel="stylesheet" href="styles.css" media="all" />

<!-- 下面的样式表只有低优先级所必需声明的样式 -->
<link rel="stylesheet" href="sm.css" media="(min-width: 20em)" /><link rel="stylesheet" href="md.css" media="(min-width: 64em)" /><link rel="stylesheet" href="lg.css" media="(min-width: 90em)" /><link rel="stylesheet" href="ex.css" media="(min-width: 120em)" /><link rel="stylesheet" href="print.css" media="print" />

可以看得,根据样式加载优先级分解样式表可以减少渲染阻塞时间。

4. 避免 @import 包含多个样式表

使用 @import 时,我们可以在一个样式表中加载另一个样式表。当我们在处理大型项目时,使用 @import 可使代码更简洁。

关于 @import 的一个主要事实是,它是阻塞调用的,因为它必须发出网络请求以获取文件,解析文件并将其包含在样式表中。如果在样式表中嵌套了 @import,将会影响渲染性能。

style.css
@import url("windows.css");

# windows.css
@import url("componenets.css");
Waterfall with imports
Waterfall with imports

除了使用 @import 之外,我们还可以使用多个链接来获得更高的性能,因为它允许并行加载样式表。

Waterfall with linking
Waterfall with linking

结论

除了本文讨论的 4 个 CSS 技巧外,我们很难使用其他 CSS 方法来改善网页性能。CSS 的最新功能之一,即 content-visibility ,在未来看起来很有希望,因为它可以通过页面渲染获得多方面的性能提升。

最重要的是,我们无需编写任何 JavaScript 代码即可获得性能提升。

我相信你可以结合上述的某些 CSS 功能,最终能为用户构建性能更好的 Web 应用程序。希望本文对你能有所帮助,如果你知道其他任何可以提高 Web 应用程序的性能的 CSS 技巧,请在下面的评论中回复。谢谢!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注