重绘是如何影响网页性能?

377 阅读5分钟

1、什么是重绘

重绘,又称回流,是指布局的重新计算,当跟布局相关联的属性(width、height、margin等)发生变更的时候,就会触发重绘和回流。它的发生有可能是有目的性的,也有可能是我们预期之外的。

例如,我们从一个列表视图切换到表格视图时,或者我们从简体切换到繁体时,回流就会在浏览器悄悄进行。那回流会有什么影响呢?要了解这个,我们需要了解浏览器渲染的原理。

2、刷新频率和像素管道

刷新频率

目前,大多数设备的屏幕刷新率为每秒 60 次。每次刷新都会生成您看到的视觉输出,通常称为“帧”。以下视频中演示了帧的概念:

image.png

但我们的网页不一定能在16.66 毫秒时生产出一帧的图像(实际上,浏览器对于每一帧都有自己的开销,给我们的时间只有10 毫秒)这就会造成感官上的卡顿。所以我们应该尽量减少不必要的开支,避免重绘和高强度的运算。

像素管道

在浏览器中,像素管道指的是将 HTML、CSS 和 JavaScript 转换为屏幕上可见像素的过程。这包括解析、样式计算、布局、绘制和合成等步骤。

完整的像素管道,包含五个步骤:JavaScript、样式、布局、绘制和合成。

  • JavaScript:JavaScript 通常用于处理会使界面发生视觉变化的工作。

  • 样式计算:根据匹配的选择器,计算出哪些 CSS 规则应用于哪些 HTML 元素的过程。

  • 布局:一旦浏览器知道对某个元素应用了哪些规则,它就可以开始计算页面的几何图形,例如元素占据了多少空间以及元素在屏幕上的显示位置。在 Web 的布局模型中,一个元素可能会影响其他元素。例如,<body> 元素的宽度通常会影响其子元素在树中各下层的尺寸,因此对浏览器来说,这个过程可能会相当复杂。

  • 绘制:绘制是填充像素的过程。它涉及到在计算完元素在网页上的布局后绘制文本、颜色、图片、边框、阴影,基本上还包括元素的每个视觉方面。绘制通常在多个表面(通常称为图层)上完成。

  • Composite:由于网页的某些部分可能会绘制到多个图层上,因此它们需要以正确的顺序应用到屏幕上,才能使网页按预期呈现。这对于与其他元素重叠的元素尤为重要,因为错误可能会导致一个元素错误地显示在另一个元素之上。

您可能听说过与“绘制”结合使用的“光栅化”一词。这是因为绘制实际上分为两个任务:

  1. 创建绘制调用列表。
  2. 填充像素。

后者称为“光栅化”,因此每当您在开发者工具中看到绘制记录时,都应将其视为包含光栅化。作为开发者,我们是无法控制光栅化的。

上面的五个步骤不全都是必须的,实际上,会根据代码是否影响布局和图像,而跳过布局和绘制阶段。

3、重绘是如何影响性能

重绘发生的时候,需要经过像素管道更新页面显示,在这个过程涉及大量的CPU资源来运行计算和更新渲染树。由于CPU可能会被这些任务压得喘不过气来,它处理用户交互和脚本执行等其他任务的能力会下降,这导致渲染速度变慢,响应能力下降。

CPU作为计算机的大脑,如果因繁忙而无法处理其他任务可能会导致明显的延迟、布局变化和页面无响应,这直接影响用户与网站的互动方式。

谷歌为了衡量这类的影响,引入了性能指标-CLS,累积布局偏移(Cumulative Layout Shift,CLS),用于衡量页面上元素位置发生变化的频率和程度。为了提供良好的用户体验,页面的 CLS 应保持在 0.1. 或更少,其值越高则性能越差。

像谷歌首页这样的简单布局就没有CLS,因为它们只包含很少的元素。

4、总结

回流是网页渲染中不可避免的一部分,但频繁的回流会显著降低页面性能。了解回流的成因及其对性能的影响,并采取适当的优化策略,可以有效提升网页的渲染性能,从而提供更流畅的用户体验。

导致回流的操作

许多常见的操作都可能触发回流,包括但不限于:

  • DOM节点的增删改

  • 改变元素的尺寸(Width、Height)

  • 改变元素的边距填充(Margin、Padding)

  • 修改字体大小

  • 显示或隐藏元素

优化渲染性能的策略

为了减少回流带来的负面影响,提高网页的渲染性能,可以考虑以下优化策略:

  1. 批量修改DOM:
    将多次对DOM的小修改合并成一次大的修改,减少回流次数。
  2. 使用class的方式批量更新样式:
    避免逐一修改样式属性,使用class的方式一次性更新,减少回流次数。
  3. 最小化布局的重计算:
    在JavaScript中访问和修改布局属性(如offsetWidth、scrollTop)时,要小心触发回流,尽量减少这些操作。
  4. 文档片段(DocumentFragment):
    通过文档片段一次性插入大量的DOM节点,而不是逐一插入,减小回流的次数。
  5. CSS的硬件加速:
    利用CSS的硬件加速属性(如transform、opacity)避免CPU的过多计算,提升渲染效率。