缩小样式计算的范围并降低其复杂性

JavaScript 通常是触发视觉变化的因素。有时,它会直接通过样式操作进行这些更改,有时则通过计算来产生视觉变化,例如搜索或排序数据。时间安排不当或长时间运行的 JavaScript 可能是导致性能问题的常见原因,您应尽可能减少其影响。

样式计算

通过添加和移除元素、更改属性、类或播放动画来更改 DOM 会导致浏览器重新计算元素样式,并且在许多情况下,还会重新计算网页的部分或全部布局。此过程称为“样式计算”

浏览器通过创建一组匹配的选择器来确定哪些类、伪选择器和 ID 适用于任何给定元素,从而开始计算样式。然后,它会处理匹配选择器的样式规则,并确定元素的最终样式。

样式重新计算在互动延迟时间中的作用

Interaction to Next Paint (INP) 是一项以用户为中心的运行时效果指标,用于评估网页对用户输入的总体响应情况。它衡量的是从用户与网页互动到浏览器绘制下一个帧(向界面显示相应的视觉更新)之间的互动延迟时间。

互动的一个重要组成部分是渲染下一帧所需的时间。为呈现下一帧而完成的渲染工作由许多部分组成,包括在布局、绘制和合成工作之前发生的网页样式计算。本指南侧重于样式计算费用,但缩短互动总渲染时长的任何部分也会缩短总延迟时间。

降低选择器的复杂性

简化 CSS 选择器有助于加快网页的样式计算速度。 最简单的选择器仅使用类名称在 CSS 中引用元素:

.title {
  /* styles */
}

但是,随着任何项目的增长,它可能需要更复杂的 CSS,并且您最终可能会得到如下所示的选择器:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

为了确定这些样式如何应用于网页,浏览器必须有效地询问“这是具有 title 类且父级具有 box 类的元素吗?该元素是其父元素的第 n-1 个子元素吗?浏览器可能需要一些时间才能确定这一点。为了简化此操作,您可以将选择器更改为更具体的类名称:

.final-box-title {
  /* styles */
}

这些替换类名称可能看起来很奇怪,但它们可以大大简化浏览器的工作。例如,在之前的版本中,浏览器要了解某个元素是否是其类型的最后一个元素,必须先了解所有其他元素,才能确定其后是否有可能是 nth-last-child 的元素。这比仅根据类名称将选择器与元素匹配在计算上要昂贵得多。

减少要设置样式的元素数量

另一个性能考虑因素(通常比选择器复杂性更重要)是元素发生变化时需要完成的工作量。

一般来说,计算计算出的元素样式的最坏情况成本是元素数量乘以选择器数量,因为浏览器需要至少针对每个样式检查每个元素一次,以查看是否匹配。

样式计算可以直接针对几个元素,而不是使整个页面失效。在现代浏览器中,这方面的问题往往较少,因为浏览器不一定需要检查更改可能影响的所有元素。另一方面,旧版浏览器并不总是针对此类任务进行优化。在可能的情况下,您应减少失效元素的数量

衡量样式重新计算费用

您可以通过多种方式衡量浏览器中的样式重新计算成本。每种方法都取决于您是想在开发环境中在浏览器中进行精准衡量,还是想衡量实际用户在您的网站上完成此流程所需的时间。

在 Chrome 开发者工具中衡量样式重新计算成本

衡量样式重新计算成本的一种方法是使用 Chrome 开发者工具中的“性能”面板。如需开始使用,请执行以下操作:

  1. 打开开发者工具。
  2. 前往效果标签页。
  3. 勾选 选择器统计信息复选框(可选)。
  4. 点击录制
  5. 与网页互动。

停止录制后,您会看到类似下图的内容:

显示样式计算的开发者工具。
显示样式计算的开发者工具报告。

顶部的条带是一个微型火焰图,其中还绘制了每秒帧数。activity 越靠近条带底部,浏览器绘制帧的速度就越快。如果您看到火焰图顶部趋于平缓,上方有红色条,则表示您有工作导致帧运行时间过长。

放大 Chrome 开发者工具中已填充的“性能”面板的活动摘要中的问题区域。
开发者工具活动摘要中的长时间运行帧。

在滚动等互动期间出现长时间运行的帧值得仔细检查。如果您看到一个较大的紫色块,请放大相应活动,然后选择任何标记为重新计算样式的工作,以详细了解可能开销较大的样式重新计算工作。

获取长时间运行的样式计算的详细信息,包括重要信息,例如受样式重新计算工作影响的元素数量。
在开发者工具摘要中,长时间运行的样式重新计算仅需 25 毫秒多一点。

点击相应事件会显示其调用堆栈。如果渲染工作是由用户互动引起的,则会调用触发样式更改的 JavaScript。它还会显示更改影响的元素数量(在本例中略高于 900 个元素)以及样式计算所用的时间。您可以利用此信息开始尝试在代码中寻找修复方法。

如果您在执行轨迹之前,在性能面板设置中选中了选择器统计信息复选框,那么轨迹中的底部面板将包含一个同名标签页。

CSS 选择器统计信息表格,显示在 Chrome 开发者工具的“性能”面板中。此表包含标题以及相应的数据,例如经过的时间、匹配尝试次数、匹配次数、不匹配节点的百分比、选择器以及它们所在的样式表。
选择器统计信息表,如 Chrome 开发者工具的“性能”面板中所示。

此面板可提供有关每个选择器的相对费用的实用数据,以便您识别费用较高的 CSS 选择器。

如需了解详情,请参阅 CSS 选择器统计信息文档

衡量真实用户的样式重新计算成本

如果您想知道网站的真实用户需要多长时间才能完成样式重新计算,Long Animation Frames API 可为您提供必要的工具。此 API 的数据已添加到 web-vitals JavaScript 库中,包括样式重新计算时间。

如果您怀疑互动的呈现延迟是导致网页 INP 的主要因素,则需要确定有多少时间用于重新计算网页上的样式。如需了解详情,请参阅如何衡量实际应用中的样式重新计算时间

资源