重绘和重排(回流)

重绘和重排(回流)

  • 重绘:给元素设置一些CSS样式,但不改变形状。比如说visibilitycolorbackground-coloroutline这些之类的就会触发重绘,重绘不会重新布局。重绘不一定重排

  • 重排:元素发生形状的变化,位置的变化,渲染树需要重新计算就会触发重排。像设置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-changewill-change属性参考


作者:叽叽复饥饥
链接:https://juejin.cn/post/6905970139934654477
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/qihang0/p/14137115.html