JavaScript 通常是视觉更改的触发器。有时,它会直接通过样式操作进行更改,有时则会通过导致视觉更改的计算(例如搜索或排序数据)进行更改。时间安排不当或长时间运行的 JavaScript 是导致性能问题的常见原因,因此您应尽可能减少其影响。
样式计算
通过添加和移除元素、更改属性、类或播放动画来更改 DOM 会导致浏览器重新计算元素样式,在许多情况下,还会重新计算网页的部分或全部布局。此过程称为样式计算。
浏览器会通过创建一组匹配的选择器来确定哪些类、伪类选择器和 ID 适用于任何给定元素,从而开始计算样式。然后,它会处理匹配选择器中的样式规则,并确定元素具有哪些最终样式。
样式重新计算在互动延迟时间中的作用
Interaction to Next Paint (INP) 是一种以用户为中心的运行时性能指标,用于评估网页对用户输入的总体响应情况。该指标用于衡量从用户与网页互动到浏览器绘制下一个帧(显示界面相应视觉更新)之间的互动延迟时间。
互动的一个重要组成部分是绘制下一帧所需的时间。为了呈现下一帧,所执行的渲染工作由许多部分组成,包括在布局、绘制和合成工作之前进行的页面样式计算。本指南重点介绍样式计算开销,但缩短互动总渲染时长的任何部分也会缩短其总延迟时间。
降低选择器的复杂性
简化 CSS 选择器有助于加快网页的样式计算速度。 最简单的选择器只需使用类名称即可在 CSS 中引用元素:
.title {
/* styles */
}
但是,随着任何项目的发展,都可能需要更复杂的 CSS,最终您可能会得到如下所示的选择器:
.box:nth-last-child(-n+1) .title {
/* styles */
}
为了确定这些样式如何应用于网页,浏览器必须有效地询问“这是一个类为 title
的元素,其父元素的类为 box
,并且是其父元素的 minus-nth-plus-1 个子元素吗?”浏览器可能需要一些时间来确定这一点。为简化起见,您可以将选择器更改为更具体的类名称:
.final-box-title {
/* styles */
}
这些替换类名称可能看起来很奇怪,但它们可以让浏览器的工作变得更加简单。例如,在旧版中,如果浏览器要知道某个元素是其类型的最后一个元素,则必须先知道所有其他元素的所有信息,以确定其后面的任何元素是否可能是 nth-last-child
。与仅根据类名称将选择器与元素进行匹配相比,这种方法的计算开销可能会高得多。
减少要设置样式的元素数量
另一个性能注意事项(通常比选择器复杂性更重要)是元素发生变化时需要执行的工作量。
一般来说,计算计算元素样式的最坏情况开销是元素数量乘以选择器数量,因为浏览器需要至少对每个元素与每种样式进行一次检查,以确定是否匹配。
样式计算可以直接定位到几个元素,而不是使整个网页失效。在现代浏览器中,这往往不是什么问题,因为浏览器并不总是需要检查更改可能会影响的所有元素。另一方面,旧版浏览器并不总是针对此类任务进行了优化。您应尽可能减少失效元素的数量。
衡量样式重新计算费用
您可以通过以下几种方式衡量浏览器中样式重新计算的开销。这两种方法各有优点,具体取决于您是想在开发环境中的浏览器中衡量,还是想衡量真实用户在您的网站上完成此过程所需的时间。
在 Chrome 开发者工具中衡量样式重新计算开销
衡量样式重新计算开销的一种方法是使用 Chrome 开发者工具中的性能面板。如需开始使用,请执行以下操作:
- 打开开发者工具。
- 前往效果标签页。
- 选中选择器统计信息复选框(可选)。
- 点击录制。
- 与网页互动。
停止录制后,您会看到如下图所示的内容:

顶部的条状图是迷你火焰图,还会绘制每秒帧数。activity 越靠近条状标签页底部,浏览器绘制帧的速度就越快。如果您看到火焰图在顶部趋于平稳,并且上面有红色条,则表示有工作会导致帧运行时间过长。

滚动等互动期间出现的长时间运行的帧值得仔细研究。如果您看到一个大的紫色块,请放大该 activity,然后选择标记为重新计算样式的任何工作,以详细了解可能耗费大量资源的样式重新计算工作。

点击相应事件即可显示其调用堆栈。如果渲染工作是由用户互动引起的,则会调用触发样式更改的 JavaScript。它还会显示更改影响的元素数量(在本例中,仅有 900 多个元素)以及样式计算所用的时间。您可以使用这些信息开始尝试在代码中查找修复方法。
如果您在跟踪之前勾选了效果面板设置中的选择器统计信息复选框,则轨迹底部的面板中会显示一个同名标签页。

此面板会提供有关每个选择器相对开销的实用数据,以便您识别开销较高的 CSS 选择器。
如需了解详情,请参阅 CSS 选择器统计信息文档。
衡量真实用户的样式重新计算开销
如果您想知道网站的真实用户需要多长时间才能重新计算样式,Long Animation Frames API 提供了实现此目的所需的工具。此 API 中的数据已添加到 web-vitals
JavaScript 库,包括样式重新计算时间。
如果您怀疑互动呈现延迟是导致网页 INP 的主要原因,则需要确定在重新计算网页上的样式时花费了多少时间。如需了解详情,请参阅如何在现场测量样式重新计算时间。