什么是重绘?
-
重绘(repaint): 当我们对Dom的修改,导致了样式的变化比如:颜色、font-weight等属性的时候,却并未影响到几何属性(:比如盒子的weidth/height/position/display等)时,浏览器不需要重新计算元素的几何属性,直接为该元素绘制新的样式;
-
回流(reflow): 当我们对DOM的修改引发了DOM几何尺寸的变化时候(比如:修改了元素的width/height/display:),浏览器需要重新计算元素的几何属性;这时候,会影响到其他元素的几何属性和位置,然后再讲计算结果绘制出来;这个过程叫做回流(重排)
回流必定会发生重绘,重绘不一定会引发回流 当我们在页面初始化的时候,或者交互过程中,存在着频繁的重绘或者回流,这个过程,会很大程度的影响性能;因为回流所需要的成本比重绘高的多,所以,能够使用重绘的方式解决的问题,尽量避免使用回流的方式解决;
常见引起回流的属性和方法:
- 任何能够改变几何信息的操作(元素的位置或者大小),都会触发回流;
- 添加或者删除可见的DOM元素;
- 元素尺寸的改变:margin /padding/border/width/height;
- 内容变化:input/textarea输入内容时;
- 浏览器窗口尺寸改变—-resize事件发生时;
- 计算offsetWith/height属性时;
- 设置style属性的值;
常见引起重绘属性和方法:
- color
- visibility
- text-decoration
- background /-image/position/repeat/size
- outline/-color/style/width
- border-style/radius
- box-shadow
如何减少回流、重绘:
-
使用 transform 替代 top
-
使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)
-
不要把节点的属性值放在一个循环里当成循环里的变量。
- 获取offsetTop 导致回流; for(let i=0;i<1000;i++){ console.log(document.querySelector('.container').style.offsetTop); }
-
不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
-
动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用 requestAnimationFrame
-
CSS 选择符从右往左匹配查找,避免节点层级过多
-
将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于 video 标签来说,浏览器会自动将该节点变为图层
参考
转载于:https://juejin.im/post/5cb6937ef265da03af27cbc8