重绘(repaint)与回流(reflow)

页面从加载到完成,首先是构建DOM树,然后根据DOM节点的几何属性形成render树(渲染树),当渲染树构建完成,页面就根据DOM树开始布局了,渲染树也根据设置的样式对应的渲染这些节点。

在这个过程中,回流与DOM树,渲染树有关,重绘与渲染树有关。

重绘和回流的区别

当增删DOM节点、修改元素的宽高、页面布局发生变化、DOM树结构发生变化,那么肯定要重新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染,这个过程叫回流。

当给元素更换颜色,不会影响页面布局,DOM树不发生变化,但颜色改变了,渲染树会重新渲染页面,这就是重绘。

回流的代价要远大于重绘。回流必然会造成重绘,但重绘不一定会造成回流。

1、引起DOM树结构变化,页面布局变化的行为叫回流,且回流一定伴随重绘

2、只是样式的变化,不会引起DOM树变化,页面布局变化的行为叫重绘,且重绘不一定会伴随回流

3、回流往往伴随着布局的变化,代价较大

4、重绘只是样式的变化,结构不会变化

怎么减少回流

回流要重新构建DOM树,渲染树也得重新渲染,页面开销较大,如何避免回流呢?

1、DOM的增删行为,如果要加多个子元素,最好使用DocumentFragment。

2、几何属性的变化,比如元素宽高变了,字体大小变了,这种直接会引起页面布局变化的操作也会引起回流。如果需要改变多个属性,可以将这些属性定义在一个class中,直接修改class名,这样只会引起一次回流。

3、元素位置的变化,修改一个元素的左右margin,padding之类的操作,所以在做元素位移的动画,不要更改margin之类的属性,可以使用定位脱离文档流后改变位置。

4、获取元素的偏移量属性,例如获取一个元素的scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之类的属性,浏览器为了保证值的正确也会回流取得最新的值,所以要多次操作,可以做个缓存。

5、页面初次渲染中的回流,这种无法避免。

6、浏览器窗口尺寸改变,触发了resize事件,导致回流。

回流一定伴随着重绘,所以上面的行为都会重绘,除此之外,例如修改背景颜色,字体颜色之类不影响布局的行为都只引发重绘。