一、定义
回流:浏览器根据CSS,确定各个DOM在浏览器上的位置和尺寸。
重绘:确定好位置、大小和其他属性后,浏览器对DOM进行绘制。
浏览器解析渲染过程:
- 解析HTML,生成DOM树;解析CSS,生成CSSOM树;
- 将DOM树和CSSOM树结合,生成渲染树;
- Layout回流:根据渲染树,进行回流,计算节点的几何信息;
- Painting重绘:根据渲染树和几何信息,对节点进行绘制;
- Display:将像素发送到CPU,展示到页面上。
二、触发时机
页面第一次加载时,回流和重绘都会触发一次。
回流触发时机
- 添加、删除DOM元素
- 修改DOM元素的位置、尺寸
- 内容发生改变
- 浏览器的窗口尺寸变化
- 读取offset、cilent、scroll系列的尺寸,因为这些尺寸都是需要即使计算得到的,因此会进行回流
重绘触发时机
- 所有触发回流的操作都会触发回流
- 修改颜色、阴影和文字方向
浏览器优化机制
浏览器为60hz,即每过1/60s才会批量处理一次重绘和回流。
三、如何避免
- 通过改变元素的class类名设定元素的样式(可以一下子批量修改)
- 使用display:fixed/absolute使元素脱标,避免影响其他元素
- JS创建元素时,使用DocumentFragment,最后再一次性插入到文档中
- 避免使用table布局,因为其中一个元素改变就会导致整个table回流
- 减少对offset等的读取
- 离线操作,即先把元素display设置为none,然后再修改属性,最后再修改回来
let container = document.getElementById('container')
container.style.display = 'none'
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'
...(省略了许多类似的后续操作)
container.style.display = 'block'