面试中,经常会问到:
“重排与重绘的概念,什么情况触发,如何优化等”
本文就来解答下,上面的问题
01
渲染过程
首先,我们来了解下浏览器的渲染过程

浏览器生成渲染树的过程

02
重排与重绘概念
重排(回流/reflow):当渲染树的一部分必须更新并且节点的尺寸发生了变化,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。
重绘(repaint):是在一个元素的外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重绘不一定需要重排,重排必然会导致重绘

03
什么情况会触发
触发重排的条件:任何页面布局和几何属性的改变都会触发重排。
比如:
offsetLeft/Top/Height/Width,
clientTop/Left/Width/Height,
scrollTop/Left/Width/Height,
width/height,
getComputedStyle(),
currentStyle(IE)
重绘发生的情况:
重绘发生在元素的可见的外观被改变,但并没有影响到布局的时候。比如,仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)

04
优化
重绘重排的代价:耗时,导致浏览器卡慢。
所以,需要优化来减少重绘重排的发生
css 优化
1. 尽可能在DOM树的最末端改变class
2. 避免设置多层内联样式
3. 动画效果应用到position属性为absolute或fixed的元素上
4. 避免使用table布局
5. 使用css3硬件加速,可以让transform、opacity、filters等动画效果不会引起回流重绘
js 优化
1. 避免使用JS一个样式修改完接着改下一个样式,最好一次性更改CSS样式,或者将样式列表定义为class的名称
2. 避免频繁操作DOM,使用文档片段创建一个子树,然后再拷贝到文档中
3. 先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发回流和重绘
4. 避免循环读取offsetLeft等属性,在循环之前把它们存起来
5.对于复杂动画效果,使用绝对定位让其脱离文档流,否则会引起父元素及后续元素大量的回流
参考:
https://segmentfault.com/a/1190000018452924
https://zhuanlan.zhihu.com/p/154266528
https://blog.csdn.net/sophia_little/article/details/79613990