重排与重绘
首先说明一个逻辑关系:
重排一定会引起重绘,而重绘不一定引起重排
我们知道在渲染一个页面的时候,会下载所有组件,html,css,js,图片等等,然后开始解析生成两个内部数据结构–-DOM树和渲染树
重排:当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。重排一定伴随着重绘。
重绘:是一个元素外观的改变所触发的浏览器行为,例如改变visibility、outline、背景色等属性(上面说到的其他属性)。浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。重绘不会带来重新布局,并不一定伴随重排。
我们说一下引起触发重排的一些操作
- 修改DOM元素几何属性:
修改元素大小,位置,内容(一般只有重绘,但是内容可能导致元素大小变化)
- DOM树结构发生变化
当DOM树的结构变化时,例如节点的增减、移动等,也会触发重排。浏览器引擎布局的过程,类似于树的前序遍历,是一个从上到下从左到右的过程。 通常在这个过程中,当前元素不会再影响其前面已经遍历过的元素。所以,如果在body最前面插入一个元素,会导致整个文档的重新渲染,而在其后插入一个元 素,则不会影响到前面的元素。
- 改变浏览器大小
减少重排,提高性能
我们知道重排其实大大消耗着浏览器的性能,每一次的DOM操作,都会引起一次重排,应对方法是,尽量减少重绘的次数,减少重排次数,缩小重排的影响范围
-
合并多次操作
类似这种,比多次的dom操作合并成为一次通过cssText进行操作
ele.style.cssText = ‘border-left: 1px; border-right: 2px; padding: 5px;’; -
将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
-
由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。但是这可能导致浏览器的闪烁。
-
在内存中多次操作节点,完成后再添加到文档中去(可使用fragment元素)。例如要异步获取表格数据,渲染到页面。可以先取得数据后在内存中构建整个表格的html片段,再一次性添加到文档中去,而不是循环添加每一行。