1、重绘 Repaint:元素样式的改变
2、回流 Reflow:元素大小,位置的改变,触发了重新布局,导致渲染树重新计算布局和渲染
第一次渲染页面的时候:触发一次回流和重绘
回流一定会触发重绘,重绘不一定回流。
重绘不是很消耗性能,回流很消耗性能(DOM元素的大小和位置信息都要重新计算一遍),而且一旦发生回流,重新计算完后,还需要重绘。
1、获取样式的代码或修改样式的代码写在一起。
因为现代浏览器默认增加了渲染队列机制,以此减少回流和重绘
// 一次回流重绘
box.style.width = '200px';
box.style.height = '200px';
box.style.margin = '20px';
注意:遇到修改样式的代码会进入渲染队列,仅直到获取样式的代码为止,会将队列里的任务先执行渲染完,形成一次DOM的回流和重绘,所有将获取样式的代码或修改样式的代码写在一起可以减少回流和重绘。
// 三次回流和重绘
box.style.width = '200px';
console.log(box.style.width); //=>中断渲染队列,立即渲染一次,引发一次DOM回流和重绘 200px
box.style.height = '200px';
console.log(box.offsetHeight);
box.style.margin = '20px';
// 一次回流重绘
box.style.width = '200px';
box.style.height = '200px';
box.style.margin = '20px';
console.log(box.style.width);
console.log(box.offsetHeight);
2、使用documentFragment文档碎片批量修改dom
documentFragment不是真实的dom节点,修改documentFragment不会出发回流和重绘,可以在documentFragment上操作完后,在覆盖到真实dom上,浏览器会智能判断,将重流和重绘只限制到相关的子树上面。
3、动画使用absolute和fixed定位,脱离文档流,减少对其他元素的影响。
使用translate实现动画,不会引发重绘回流
4、隐藏显示元素尽量使用visibility:hidden/visible,不要使用display:none
visibility所占据的空间位置仍然存在,仅仅是在视觉上看不见,不会有回流。
5、window.requestAnimationFrame
使用window.requestAnimationFrame()
,因为它可以把代码推迟到下一次重绘之前执行,而不是立即要求页面重绘。
其他:文件打包优化、请求接口的优化,css的优化