zoukankan      html  css  js  c++  java
  • 重排和重绘

    重排:当DOM树变化影响了元素几何属性(宽、高等等)浏览器此时需要重新计算几何属性;并且页面其他元素的几何属性也受到了影响;这样渲染树就发生了变化;需要充排(reflow)

    重绘:当DOM的变化仅仅影响了背景色等等非几何属性;就发生了重绘;布局没有变化;

    触发重排: 页面初始渲染

                      添加、删除可见DOM元素

            改变元素位置

                      改变元素尺寸(宽、高、内外边距、边框等)

                      改变元素内容(文本或图片等)

                      改变窗口尺寸

    不同情况下重排的范围和程度会不同

    某些情况下甚至会发生整个页面、比如滑动滚动条

    浏览器优化:渲染队列 

      用js修改div样式       div.style.left='10px';

               div.style.top='10px';

               div.style.width='10px';

               div.style.height='10px';

           这样我们修改了元素的 left、top、width、height属性

           满足了发生重排的条件 。理论上会发生四次重排

           但是实际只发生了一次

           因为我们现代的浏览器都有渲染队列的机制

            当我改变了元素的一个样式会导致浏览器发生重排或者重绘时候

           它会进入一个渲染队列

            然后浏览器继续往下看,若果还有样式修改同样加入队伍

       直到没有样式修改

       浏览器会按照渲染队列批量执行来优化重排过程,一并修改样式

            把四次重排优化为一次

           

              但如果我们想在后台打印

            

              千万不要写这样的代码,因为发生了4次重排
              不懂了,不是说浏览器有渲染队列优化机制吗?
              为什么这样写就会发生4次重排
              因为offsetLeft/Top/Width/Height非常叼
              它们会强制刷新队列要求样式修改任务立刻执行
              想一想其实这么做是有道理的
              毕竟浏览器不确定在接下来的代码中你是否还会修改同样的样式
             为了保证获得正确的值,它不得不立刻执行渲染队列触发重排(错的不是我,是这个世界)

             

        以下属性或方法会刷新渲染队列

    •   offsetTop、offsetLeft、offsetWidth、offsetHeight
    •   clientTop、clientLeft、clientWidth、clientHeight
    •   scrollTop、scrollLeft、scrollWidth、scrollHeight
    •   getComputedStyle()(IE中currentStyle)

    元素批量修改

    现在我们想要向ul中循环添加大量li
    (如果ul还不存在,最好的办法是先循环添加li到ul,然后再把ul添加到文档,1次重排)

    var ul = document.getElementById('demo');
    for(var i = 0; i < 1e5; i++){
        var li = document.createElement('li');
        var text = document.createTextNode(i);
        li.appendChild(text);
        ul.appendChild(li);
    }

    我可以做出下面的优化

    var ul = document.getElementById('demo');
    ul.style.display = 'none'; <--
    for(var i = 0; i < 1e5; i++){
        var li = document.createElement('li');
        var text = document.createTextNode(i);
        li.appendChild(text);
        ul.appendChild(li);
    }
    ul.style.display = 'block'; <--
    var ul = document.getElementById('demo');
    var frg = document.createDocumentFragment(); <--
    for(var i = 0; i < 1e5; i++){
        var li = document.createElement('li');
        var text = document.createTextNode(i);
        li.appendChild(text);
        frg.appendChild(li); <--
    }
    ul.appendChild(frg); <--
    var ul = document.getElementById('demo');
    var clone = ul.cloneNode(true); <--
    for(var i = 0; i < 1e5; i++){
        var li = document.createElement('li');
        var text = document.createTextNode(i);
        li.appendChild(text);
        clone.appendChild(li); <--
    }
    ul.parentNode.replaceChild(clone,ul); <--

    上面的方法减少重绘和重排的原理很简单

        • 元素脱离文档
        • 改变样式
        • 元素回归文档

    而改变元素就分别使用了隐藏元素、文档碎片和克隆元素
    上面的方法我认为仅仅是理论上可以优化重排重绘次数
    现代浏览器的优化可能会超过我们的想象

          

  • 相关阅读:
    hdfs fsck命令查看HDFS文件对应的文件块信息(Block)和位置信息(Locations)
    更高的压缩比,更好的性能–使用ORC文件格式优化Hive
    InfluxDB基本概念和操作
    InfluxDB部署
    Zookeeper运维小结--CancelledKeyException
    Zookeeper源码编译为Eclipse工程(win7下Ant编译)
    ZooKeeper Observers解决节点过多时写性能下降问题
    ZooKeeper日志与快照文件简单分析
    ZooKeeper Administrator's Guide A Guide to Deployment and Administration(吃别人嚼过的馍没意思,直接看官网资料)
    ZOOKEEPER解惑
  • 原文地址:https://www.cnblogs.com/stone5/p/9041154.html
Copyright © 2011-2022 走看看