重绘和回流
回流
我们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM树
DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染,这个过程就叫回流
下面这些操作会导致回流 1.页面的首次渲染 2.浏览器的窗口大小发生变化 3.元素的内容发生变化 4.元素的尺寸或者位置发生变化 5.元素的字体大小发生变化 6.激活CSS伪类 7.查询某些属性或者调用某些方法 8.添加或者删除可见的DOM元素 在触发回流(重排)的时候,由于浏览器染页面是基于流式布局的,所以当触发回流时,会导致周围的DOM元素重新排列,它的影响范围有两种: -全局范围:从根节点开始,对整个渲染树进行重新布局 -局部范围:对渲染树的某部分或者一个渲染对象进行重新布局
重绘
当你给一个元素更换颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但颜色变了,渲染树得重新渲染页面,这就是重绘。
元素样式的改变(但宽高、大小、位置不变) color、background 相关属性: background-color、background-image等 outline 相关属性: outline-color、 outline-width 、 text-decoration。 border-radius、visibility、 box-shadow
回流一定会触发重绘,而重绘不一定会回流
如何避免回流与重绘?
使用absolute或者fixed,使元素脱离文档流,这样他们发生变化就不会影响其他元素
将元素先设置 display: none ,:操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘
将DOM的多个读操作(或者写操作)放在一起,而不是读写操作穿插着写。这得益于浏览器的渲染队列机制。
操作DOM时,尽量在低层级的DOM节点进行操作 不要使用 table 布局,一个小的改动可能会使整个 table 进行重新布局 使用CSS的表达式 不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式 避免频繁操作DOM,可以创建一个文档片段 documentFragment ,在它上面应用所有DOM操作,最后再把它添加到文档中
浏览器针对页面的回流与重绘,进行了自身的优化-- 渲染队列 浏览器会将所有的回流、重绘的操作放在一个队列中,当队列中的操作到了一定的数量或者到了一定的时间间隔浏览器就会对队列进行批处理。这样就会让多次的回流、重绘变成一次回流重绘。