今天一个bug引发了我对重排和重绘的好奇
对这个知识点做个系统的了解和总结
DOM的变化引发了原生的几何属性的变化,比如宽高和位置的变化等,属于重排
完成重排后,要将重新构建的其他样式(如颜色)渲染到屏幕上,这个过程就是重绘
重排必然会引发重绘,但重绘并不一定伴随着重排
重排的触发条件:
- 添加或者删除可以的DOM元素
- 元素位置改变
- 元素本身的尺寸变化
- 内容改变
- 页面渲染器初始化
- 浏览器窗口大小发生改变
重绘和重排的开销是非常昂贵的,如果我们不停的在改变页面的布局,就会造成浏览器耗费大量的开销在进行页面的计算,这样的话,我们页面在用户使用起来,就会出现明显的卡顿。
现在的浏览器其实已经对重排进行了优化
1 | var div = document.querySelector('.div'); |
比较久远的浏览器,这段代码会触发页面2次重排,在分别设置宽高的时候,触发2次.
当代的浏览器对此进行了优化,这种思路类似于现在流行的MVVM框架使用的虚拟DOM,对改变的DOM节点进行依赖收集,确认没有改变的节点,就进行一次更新。但是浏览器针对重排的优化虽然思路和虚拟DOM接近,但是还是有本质的区别。大多数浏览器通过队列化修改并批量执行来优化重排过程。也就是说上面那段代码其实在现在的浏览器优化下,只构成一次重排。
除此之外,我们也可以针对性的做一些优化
- 最小化重排和重绘(把会引起重排和重绘的操作一起操作,尽量只重绘或重排一次)
- 缓存布局信息 缓存布局信息这个概念,在《高性能JavaScript》DOM性能优化中,多次提到类似的思想.
- 比如我现在要得到页面ul节点下面的100个li节点,最好的办法就是第一次获取后就保存起来,减少