一、回流和重绘是什么?
在html中,每个元素都可以理解成一个盒子,在浏览器解析过程中,会涉及到回流与重绘:
- 回流:在布局之后对元素的大小、位置进行改变
- 重绘:在第一次绘制完页面后,重新绘制的过程
具体的浏览器解析渲染机制如下所示:
-
解析HTML,生成DOM树,解析CSS,生成CSSOM树
-
将DOM树和CSSOM树结合,生成渲染树(Render Tree)
-
Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
-
Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
-
Display:将像素发送给GPU,展示在页面上
在页面初始渲染阶段,回流不可避免的触发,可以理解成页面一开始是空白的元素,后面添加了新的元素使页面布局发生改变
当我们对 DOM
的修改引发了 DOM
几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算的结果绘制出来
当我们对 DOM
的修改导致了样式的变化(color
或background-color
),却并未影响其几何属性时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式,这里就仅仅触发了重绘
二、什么场景会触发?
回流触发时机:
(1)DOM结构发生改变 (添加新的节点或者移除节点)
(2)布局发生改变(修改了width、height、padding、font-size等值)
(3)窗口大小发生改变
(4)调用getComputedStyle方法获取尺寸、位置信息
(5)内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所代替
(6)页面一开始渲染的时候
重绘触发时机:
(1)修改网页内容的样式时,比如文字颜色,背景颜色,边框颜色,文本方向的修改等。
(2)触发回流一定会触发重绘
三、如何避免回流?
1. 修改样式时尽量一次性修改
比如通过cssText修改,比如通过添加class修改;
2.尽量避免频繁的操作DOM
我们可以在一个DocumentFragment或者父元素中将要操作的DOM操作完成,再一次性的操作;
3.尽量避免通过getComputedStyle获取尺寸、位置等信息;
4.对某些元素使用position的absolute或者fixed
并不是不会引起回流,而是开销相对较小,不会对其他元素造成影响。
5.避免设置多项内联样式
6.避免使用css的JavaScript表达式