怎么理解回流和重绘?什么场景下会触发
最近有同学问我怎么理解回流和重绘?什么场景下会触发?我觉得这个非常有意思,值得聊一聊,算是每个前端必须掌握的知识。
首先,回流(Reflow)和重绘(Repaint)是浏览器渲染页面时两个非常重要的过程。它们之间有些联系,但也有很大的区别。简单来说,回流和重绘是两种不同类型的浏览器计算,分别负责页面布局的重新计算和样式的重新渲染。
1. 回流(Reflow)
回流是浏览器对页面布局进行重新计算的过程。在这个过程中,浏览器会计算出元素的位置、尺寸等几何信息。每当页面的布局发生变化时,都会触发回流。
触发回流的场景:
- 添加或删除 DOM 元素:当新增或删除可见的 DOM 元素时,浏览器必须重新计算页面布局。
- 元素位置变化:当元素的
position(如left、top)发生变化,浏览器需要重新计算其相对于其他元素的位置。 - 元素尺寸变化:例如,修改了元素的宽度、高度、边距、边框、内边距等都会导致回流。
- 内容变化:文本内容变化或图片替换成不同尺寸的图片时,浏览器需要重新计算布局。
- 窗口大小变化:浏览器窗口的大小变化会影响元素的布局,因此会触发回流。
- 获取布局信息:一些属性如
offsetWidth、offsetHeight、clientWidth等,都会导致浏览器立即进行回流计算。
回流通常是比较昂贵的操作,因为它需要重新计算页面上多个元素的位置和尺寸,可能会影响到页面的渲染性能。
2. 重绘(Repaint)
重绘是在回流之后发生的操作,它是浏览器在页面布局计算完成后,重新绘制元素的外观(颜色、背景、边框等)。重绘并不涉及重新计算布局或位置,通常仅仅是更新元素的视觉效果。
触发重绘的场景:
- 颜色变化:例如,修改元素的
color或background-color,这种操作不会影响布局,只会改变元素的外观,因此会触发重绘。 - 文本方向变化:例如,修改元素的
text-align或direction。 - 阴影修改:如
box-shadow或text-shadow的变化。
注意: 每次回流都会伴随重绘,但不是所有重绘都会引发回流。
3. 如何减少回流和重绘?
回流和重绘会影响页面的渲染性能,因此我们通常会尽量减少它们的触发频率。以下是一些优化建议:
减少回流:
- 避免频繁修改 DOM:尽量将 DOM 操作合并,例如批量插入节点时,可以使用
DocumentFragment。 - 避免修改尺寸和位置的属性:尽量避免频繁修改
width、height、top、left等属性。 - 尽量使用
class来改变样式:比起直接通过style属性修改单个元素的样式,使用class来批量修改样式,能减少回流的次数。 - 避免使用
table布局:table布局中的元素修改会导致整个表格的回流。 - 脱离文档流:对于动画元素,使用
position: fixed或absolute,可以让它们脱离文档流,从而减少对页面其他元素的影响。 - 硬件加速:使用 CSS3 动画时,利用硬件加速(如使用
transform和opacity)可以避免触发回流。
减少重绘:
- 减少样式修改:仅在需要的时候修改样式,避免不必要的
color、background-color等样式修改。 - 使用 CSS 动画:尽量使用 CSS 动画代替 JavaScript 动画,这样可以让浏览器利用 GPU 加速,减少对性能的影响。
浏览器的优化机制
现代浏览器会采用优化策略来减少回流和重绘的影响。例如,浏览器会将多个 DOM 操作放入一个队列中批量执行,直到满足一定条件(如操作数量达到阈值或者一定的时间间隔),再一起刷新页面。这种机制有助于提高性能,避免频繁的重排和重绘。
但是,如果你获取一些布局信息(如 offsetHeight 等),浏览器就会强制刷新这些队列,从而触发回流和重绘。所以在获取这些属性时,需要注意性能消耗。
怎么理解回流和重绘?什么场景下会触发
https://halo.527115.xyz/archives/URQSep9j