CSS 性能优化

上一页

概述:Web 性能

下一页

在开发网站时,您需要考虑浏览器如何处理您网站上的 CSS。为了减轻 CSS 可能引起的任何性能问题,您应该对其进行优化。例如,您应该优化 CSS 以减轻渲染阻塞并最大程度地减少所需的重排次数。本文将引导您了解关键的 CSS 性能优化技术。

先决条件

已安装基本软件,并具备客户端 Web 技术的基本知识。

目标

了解 CSS 对网站性能的影响,以及如何优化 CSS 以提高性能。

是否需要优化在开始优化 CSS 之前,您应该回答的第一个问题是“我需要优化什么?”。下面讨论的一些提示和技巧是良好的实践,几乎可以使任何 Web 项目受益,而有些技巧仅在某些情况下才需要。尝试在任何地方应用所有这些技巧可能是不必要的,并且可能是浪费时间。您应该弄清楚每个项目中实际需要的性能优化。

为此,您需要衡量网站的性能。如前面的链接所示,有多种不同的方法可以衡量性能,其中一些涉及复杂的性能 API。但是,入门最好的方法是学习如何使用内置浏览器网络和性能工具,以查看页面加载的哪些部分花费了很长时间,需要优化。

优化渲染浏览器遵循特定的渲染路径——只有在布局之后才会发生绘制,而布局发生在渲染树创建之后,这反过来又需要 DOM 和 CSSOM 树。

向用户显示一个无样式的页面,然后在 CSS 样式解析后重新绘制它将是一种糟糕的用户体验。出于这个原因,CSS 会阻塞渲染,直到浏览器确定需要 CSS。浏览器在下载 CSS 并构建CSS 对象模型 (CSSOM)后可以绘制页面。

为了优化 CSSOM 的构建并提高页面性能,您可以根据 CSS 的当前状态执行以下一项或多项操作

删除不必要的样式:这听起来可能很明显,但令人惊讶的是,有多少开发人员忘记清理在开发过程中添加到样式表中但最终未使用的 CSS 规则。所有样式都会被解析,无论它们是否在布局和绘制过程中使用,因此删除未使用的样式可以加快页面渲染速度。如如何从网站中删除未使用的 CSS?(csstricks.com,2019)总结的那样,对于大型代码库来说,这是一个难以解决的问题,并且没有可靠地查找和删除未使用的 CSS 的灵丹妙药。您需要努力保持 CSS 的模块化,并谨慎地考虑添加和删除的内容。

将 CSS 分割成单独的模块:保持 CSS 模块化意味着可以在稍后加载页面加载时不需要的 CSS,从而减少初始 CSS 渲染阻塞和加载时间。最简单的方法是将 CSS 分割成单独的文件,并仅加载所需的文件html

rel="stylesheet"

href="mobile.css"

media="screen and (max-width: 480px)" />

以上示例提供了三组样式——始终加载的默认样式、仅在打印文档时加载的样式以及仅由窄屏幕设备加载的样式。默认情况下,浏览器假设每个指定的样式表都会阻塞渲染。您可以通过添加包含媒体查询的media属性来告诉浏览器何时应用样式表。当浏览器看到一个它只需要在特定情况下应用的样式表时,它仍然会下载该样式表,但不会阻塞渲染。通过将 CSS 分割成多个文件,主渲染阻塞文件(在本例中为styles.css)的大小要小得多,从而减少了渲染被阻塞的时间。

压缩和压缩 CSS:一旦代码投入生产,压缩会删除文件中仅用于人类可读性的所有空格。通过压缩 CSS,您可以大大减少加载时间。压缩通常作为构建过程的一部分完成(例如,大多数 JavaScript 框架在构建准备部署的项目时都会压缩代码)。除了压缩之外,请确保您的网站托管的服务器在提供文件之前使用 gzip 等压缩方法。

简化选择器:人们通常会编写比应用所需样式更复杂的选择器。这不仅会增加文件大小,还会增加这些选择器的解析时间。例如css/* Very specific selector */

body div#main-content article.post h2.headline {

font-size: 24px;

}

/* You probably only need this */

.headline {

font-size: 24px;

}

使选择器不那么复杂和特定也有利于维护。很容易理解简单选择器在做什么,并且如果选择器不那么特定,则以后在需要时也很容易覆盖样式。

不要对超出需要的元素应用样式:一个常见的错误是使用通用选择器对所有元素应用样式,或者至少是对超出需要的元素应用样式。这种样式会对性能产生负面影响,尤其是在较大的网站上。css/* Selects every element inside the */

body * {

font-size: 14px;

display: flex;

}

请记住,许多属性(例如font-size)会继承其父元素的值,因此您无需在任何地方都应用它们。并且像Flexbox这样的强大工具需要谨慎使用。在任何地方使用它们都会导致各种意想不到的行为。

使用 CSS 雪碧减少图像 HTTP 请求:CSS 雪碧是一种技术,它将您想在网站上使用的几个小图像(例如图标)放到一个图像文件中,然后使用不同的background-position值来显示您想在每个不同位置显示的图像块。这可以大大减少获取图像所需的 HTTP 请求数量。

预加载重要资源:您可以使用rel="preload"将元素变成关键资源的预加载器。这包括 CSS 文件、字体和图像html

rel="preload"

href="ComicSans.woff2"

as="font"

type="font/woff2"

crossorigin />

rel="preload"

href="bg-image-wide.png"

as="image"

media="(min-width: 601px)" />

使用preload,浏览器会尽快获取引用的资源并将其放入浏览器缓存中,以便在后续代码中引用它们时可以更快地使用它们。预加载用户在页面早期遇到的高优先级资源很有用,这样可以使体验尽可能流畅。请注意,您还可以使用media属性创建响应式预加载器。另请参阅 web.dev 上的预加载关键资源以提高加载速度(2020)

处理动画动画可以提高感知性能,使界面感觉更灵敏,并使用户在等待页面加载时感觉正在取得进展(例如加载微调器)。但是,较大的动画和较多的动画自然需要更多的处理能力来处理,这会降低性能。

最简单的建议是减少所有不必要的动画。您还可以为用户提供一个控件/网站首选项来关闭动画,如果他们使用的是低功耗设备或电池电量有限的移动设备。您还可以使用 JavaScript 控制是否首先将动画应用于页面。还有一个名为prefers-reduced-motion的媒体查询,可用于根据用户操作系统级别的动画首选项有选择地提供动画样式或不提供动画样式。

对于必要的 DOM 动画,建议尽可能使用CSS 动画,而不是 JavaScript 动画(Web 动画 API提供了一种使用 JavaScript 直接挂接到 CSS 动画的方法)。

选择要动画化的属性接下来,动画性能很大程度上取决于您正在动画化的属性。某些属性在进行动画处理时会触发重排(因此也会触发重绘),应避免使用。这些属性包括

更改元素尺寸的属性,例如width、height、border和padding。

重新定位元素的属性,例如margin、top、bottom、left和right。

更改元素布局的属性,例如align-content、align-items和flex。

添加更改元素几何形状的视觉效果的属性,例如box-shadow。

现代浏览器足够智能,可以仅重新绘制文档的更改区域,而不是整个页面。因此,较大的动画成本更高。

如果可能,最好动画化不会导致重排/重绘的属性。这包括

变换

不透明度

过滤器

在 GPU 上进行动画处理为了进一步提高性能,您应该考虑将动画工作从主线程转移到设备的 GPU(也称为合成)。这是通过选择浏览器会自动发送到 GPU 处理的特定类型的动画来完成的;这些包括

3D 变换动画,例如transform: translateZ()和rotate3d()。

具有某些其他动画属性的元素,例如position: fixed。

应用了will-change的元素(请参阅下面的部分)。

某些元素在其自身的图层中呈现,包括