重绘和重排(回流)
重绘和重排(回流)
-
重绘:给元素设置一些CSS样式,但不改变形状。比如说
visibility
、color
、background-color
、outline
这些之类的就会触发重绘,重绘不会重新布局。重绘不一定重排。 -
重排:元素发生形状的变化,位置的变化,渲染树需要重新计算就会触发重排。像设置
display:none;
页面首次渲染
、激活伪类元素如:hover
、增删DOM元素
、移动元素位置
,改变窗口大小
这些都会发生重排。重排必定重绘。
如何优化?
-
减少重绘和重排的发生次数:比如我们修改元素的样式,可以将多次修改合并成一次修改
const el = document.querySelector('.test') el.style.margin = '5px' el.style.paddingTop = '2px' el.style.paddingBottom = '5px'
这里对DOM元素进行了多次的样式修改,每一次修改都会触发重排(现代浏览器已经做过优化,会合并成一次重排。但是旧的浏览器还是会触发多次)。所以我们就需要进行合并处理
const el = document.querySelector('.test') el.style.cssText += 'margin: 5px; padding-top: 2px; padding-bottom: 5px;'
或者直接给el添加一个新的样式类
const el = document.querySelector('.test') el.className += ' test2'
-
批量对DOM元素进行修改:
1.先让元素脱离文档流,然后display:none隐藏元素,对DOM元素进行修改,然后display: block重新显示。这里隐藏和显示DOM元素会触发重排,但是对DOM元素修改的过程并不会,这样可以减少重排次数
2.使用文档片段
document.createDocumentFragment()
const ul = document.querySelector("ul") const fragment = document.createDocumentFragment() for (let i = 0; i < 20; i++) { let li = document.createElement("li") li.innerHTML = "index: " + i ul.appendChild(li) } ul.appendChild(fragment);
-
对于复杂动画,可以将其设置为绝对定位,脱离文档流,不然会引起它的父元素和后续元素进行频繁的重排
-
CSS优化:
1.避免使用table布局
2.避免设置内联样式
3.少用calc表达式,会频发触发重排
4.将动画设置到脱离文档流的元素上面
-
使用CSS3的硬件加速:可以触发硬件加速的属性有:
transform(过渡)
、opacity(透明度)
、filters(滤镜)
、will-change
will-change属性参考
作者:叽叽复饥饥
链接:https://juejin.cn/post/6905970139934654477
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。