1、什么是重排和重绘
网页生成过程:
HTML
被HTML解析器解析成DOM
树css
则被css解析器解析成CSSOM
树- 结合
DOM
树和CSSOM
树,生成一棵渲染树(Render Tree
) - 生成布局(
flow
),即将所有渲染树的所有节点进行平面合成 - 将布局绘制(
paint
)在屏幕上
重排(也称回流): 当DOM
的变化影响了元素的几何信息(DOM
对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。 触发:
- 添加或者删除可见的DOM元素
- 元素位置改变
- 元素尺寸改变
- 元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)
- 页面渲染初始化(这个无法避免)
- 浏览器窗口尺寸改变
重绘: 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。 触发:
- 改变元素的
color、background、box-shadow
等属性
2、重排和重绘的代价究竟多大
var times = 15000;
// code1 每次过桥+重排+重绘
console.time(1);
for(var i = 0; i < times; i++) {
document.getElementById('myDiv1').innerHTML += 'a';
}
console.timeEnd(1);
// code2 只过桥
console.time(2);
var str = '';
for(var i = 0; i < times; i++) {
var tmp = document.getElementById('myDiv2').innerHTML;
str += 'a';
}
document.getElementById('myDiv2').innerHTML = str;
console.timeEnd(2);
// code3
console.time(3);
var _str = '';
for(var i = 0; i < times; i++) {
_str += 'a';
}
document.getElementById('myDiv3').innerHTML = _str;
console.timeEnd(3);
// 1: 2874.619ms
// 2: 11.154ms
// 3: 1.282ms
复制代码
3、重排优化建议:
- 分离读写操作
- 样式集中修改
- 缓存需要修改的
DOM
元素 - 尽量只修改
position:absolute
或fixed
元素,对其他元素影响不大 - 动画开始
GPU
加速,translate
使用3D
变化
transform
不重绘,不回流 是因为transform
属于合成属性,对合成属性进行transition/animate
动画时,将会创建一个合成层。这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘。浏览器会通过重新复合来创建动画帧。