什么是重绘与重排,如何减少?
是什么
reflow: 浏览器重新渲染部分或全部文档,重新计算元素位置和几何解构。页面至少发生一次重排在页面初次加载的时候。
repaint: 只改样式而不影响布局,如改: background-color
等。
触发条件
reflow
盒模型相关:
width
height
margin
padding
border
…定位、浮动:
float
position
…文字解构:
text-align
line-height
overflow
font-size
…
调整窗口大小
样式表变动
元素内容变化,尤其是输入控件
dom操作
css伪类激活
计算元素的offsetWidth、offsetHeight、clientWidth、clientHeight、width、height、scrollTop、scrollHeight
repaint
元素更新样式风格相关的属性时。
注 ⚠️:reflow 一定会 repaint,repaint 不一定会 reflow
如何避免
避免 reflow
本质上是减少对 render tree
的操作,render tree
包括 DOM
和 CSSOM
的信息。当二者都组建完毕时才进行 render tree
的合并。中途一旦遇到脚本文件就会停止组建,若涉及到对节点或样式的修改会等待修改完毕再继续组建。(这是发生在第一次加载的时候,后续的改变就是描述的那样重排的情况了)
- 直接改类名,减少分别修改样式的次数
1 | // 不好的写法 |
或者将几次修改内容拼接成一个字符串,一次性修改,其实原理同上。
1 | ele.style.cssText += "; |
- 整体搬离,减少
reflow
使用DocumentFragment进行缓存操作,引发一次回流和重绘;
DocumentFragment 是 ‘a minimal document object that has no parent.A common use for DocumentFragment is to create one, assemble a DOM subtree within it, then append or insert the fragment into the DOM using Node interface methods such as appendChild() or insertBefore()). ’
1 | document.addEventListener('DOMContentLoaded', function () { |
使用display:none,只引发两次回流和重绘;
使用cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘;
- 频繁访问属性的时候,采取缓存。
1 | // 不好的写法 |
- 替代会触发reflow和repaint的属性
比如用translate代替top,用opacity替代visibility
减少table的使用
动画实现的速度选择
对于动画新建图层