美文网首页
重绘(repaint)与回流(重排 reflow)

重绘(repaint)与回流(重排 reflow)

作者: wojiaho | 来源:发表于2019-02-27 17:55 被阅读0次

    页面呈现流程

    1. 浏览器会将获取到的HTML代码解析成一个DOM树(包括display: none的元素)
    2. 在DOM树的基础上根据节点的几何属性(margin/padding/width/height等)生成render树(不包括display: none、head节点但是会包含visibility:hidden节点)
    3. 在render树的基础上进一步渲染样式


      微信图片_20190227175527.png

    repaint、reflow概念

    回流(reflow):当render树种的元素因为大小,布局,隐藏、增减等原因而引起的重建叫做回流
    重绘(repaint):当元素的一部分属性发生变化的时候,会影响外观但是不会引起布局变化(比如background-color)而重新渲染的过程叫重绘

    引起回流的原因

    1. 页面初始化渲染
    2. DOM节点的增加和删除
    3. 元素位置发生改变
    4. 元素几何属性发生变化 - border、width、height、padding、margin
    5. 浏览器窗口发生变化(resize)
    6. 获取某些属性 - offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)
    var s = document.body.style;
    s.padding = "2px"; // 回流 + 重绘
    s.border = "1px solid red"; // 再一次 回流+重绘
    s.color = "blue"; // 再一次重绘
    s.backgroundColor = "#ccc"; // 再一次 重绘
    s.fontSize = "14px"; // 再一次 回流+重绘
    // 添加node,再一次 回流+重绘
    document.body.appendChild(document.createTextNode('abc!'));
    

    上面代码一共引起了4次回流和6次重绘,但是浏览器并不会每一条js语句就执行一次,而是等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会flush对象,进行批量处理,这样就会让多次回流、重绘变成一次回流重绘。
    当我们去获取第六点那些属性的时候,浏览器为了能给你返回一个比较精确的答案,他会提前flush队列,因为队列中可能会有影响这些值的操作,所以获取这些属性也会引起回流

    优化

    1. 使用class将多次改变样式属性的操作合并成一次操作
    var changeDiv = document.getElementById('changeDiv'); 
    changeDiv.style.color = '#093'; 
    changeDiv.style.background = '#eee'; 
    changeDiv.style.height = '200px';
    // 可以添加一个class
    div.changeDiv {
    background: #eee;
    color: #093;
    height: 200px;
    }
    为这个节点添加这个className
    document.getElementById('changeDiv').className = 'changeDiv';
    
    1. 让要操作的元素进行"离线处理",处理完后一起更新
      a)使用DocumentFragment进行缓存操作,引发一次回流和重绘
      b)使用display:none,如果要对一个元素进行复杂操作,可以先隐藏他,操作完成之后在显示,这样只引发两次回流和重绘
      c)使用cloneNode(true/false)和replaceChild,引发一次回流和重绘
    2. 将需要多次重排的元素,position属性设置为absolute或者fixed,这样此元素会脱离文档流,他的变化不会影响到其他元素。例如有动画效果的元素最好设置为绝对定位。
    3. 在内存中多次操作节点,可以一起操作完成之后再添加到文档中去。
    4. 在需要经常获取那些引起浏览器回流的属性值是,可以缓存到变量中,而不是每次去重新获取。

    参考文档:

    1. https://www.html.cn/archives/4991
    2. https://www.cnblogs.com/dujingjie/p/5784890.html

    相关文章

      网友评论

          本文标题:重绘(repaint)与回流(重排 reflow)

          本文链接:https://www.haomeiwen.com/subject/allfuqtx.html