回流(重排)、重绘、合成

23 阅读2分钟

前言

接上篇:浏览器工作原理与实践-渲染流程 - 掘金 (juejin.cn)

回流 (Reflow) 是指网页渲染引擎根据元素的尺寸、位置和显示属性来重新计算页面的排版和布局,是网页渲染过程中的一个重要步骤。

重绘 (Repaint) 是指网页渲染引擎根据显示属性 (如颜色、文字大小等) 重新绘制页面元素,不影响元素的位置和尺寸。

动作与浏览器渲染流程的对应关系:

回流 --- 布局

重绘 --- 绘制

合成 --- 合成

通过有效控制回流和重绘,可以提高网页的渲染性能。

回流(重排)

回流会触发浏览器渲染进程主线程中布局这一动作。通常是更新了元素的几何属性。

可参考下图:

image.png

从上图可以看出,如果你通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。

无疑,重排需要更新完整的渲染流水线,所以开销也是最大的。

重绘

回流会触发浏览器渲染进程主线程中绘制这一动作。通常是更新元素的绘制属性。

可参考下图:

image.png

从图中可以看出,如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。

相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高 一些。

合成

那如果你更改一个既不要布局也不要绘制的属性,会发生什么变化呢?渲染引擎将跳过布局和绘制,只执行后续的合成操作,我们把这个过程叫做合成。具体流程参考下图:

image.png

在上图中,我们使用了 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段, 直接在非主线程上执行合成动画操作。

这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

如何减少回流和重绘

虚拟 DOM 批量提交修改的作用

总结

JavaScript 引擎是在浏览器的渲染进程中的主线程中运行的。

避免妨碍到主线程是很有必要的。

参考

浏览器工作原理与实践 (geekbang.org)