美文网首页web前端
虚拟dom如何提升性能?

虚拟dom如何提升性能?

作者: 姜治宇 | 来源:发表于2021-09-02 11:44 被阅读0次

    如何降低dom的更新次数?

    先温习下dom的渲染机制(https://www.jianshu.com/p/fb7db9690e0d),当浏览器拿到了dom和css的骨架结构之后,下面就是将dom树的各元素根据尺寸和位置进行布局排列,这就是layout;然后对各元素进行上色,就是paint。
    以上过程是必不可少的,其实我们关注的重点是:一旦浏览器解析dom完毕,如何降低dom的更新次数?
    触发重新布局的话就是reflow,重新上色的话就是repaint。
    比如有这么一个ul:

    <ul>
      <li>1</li>
      <li>2</li>
    </ul>
    

    浏览器解析完毕后,如果对第2个li进行display:none和display:block的话,那就是触发了两次reflow和repaint。

    脱离文档流

    对脱离文档流的元素进行操作,就可以有效减少文档流本身的重排。
    我们熟知的css脱离文档流的方式主要是float浮动与position定位,将频繁重排的元素,position属性设为absolute或fixed是个不错的选择,因为元素脱离了文档流,它的变化不会影响到其他元素。
    还有一个比较常用的,就是文档碎片DocumentFragment。
    比如我们要给ul添加5个li节点,二者的区别是:

    直接操作DOM,需要重排5次:
    image
    使用DocumentFragment一次性添加,只需重排1次:
    image

    为检验结论是否正确,我们写段测试代码,分别对比下渲染完成的时间:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <ul id="list1"></ul>
        <ul id="list"></ul>
    
    </body>
    </html>
    <script>
        
    //直接操作DOM添加节点
    console.time("time1")
    let list1 = document.querySelector("#list1"),
        i = 50000;
    while(i--){
      list1.appendChild(document.createElement("li"))
    };
    console.timeEnd("time1")
    //使用documentFragment添加节点
    console.time("time")
    let list = document.querySelector("#list"),
        fragment = document.createDocumentFragment(),
        n = 50000;
    while(n--){
      fragment.appendChild(document.createElement("li"));
    };
    list.appendChild(fragment);
    console.timeEnd("time")
    
    </script>
    

    运行结果:
    time1:26 毫秒
    time:24 毫秒
    PS:
    这段代码很有意思,如果你在谷歌浏览器测试,结果反而是直接操作dom比较快,这是因为谷歌本身做了优化设计,会将短时间内的多次reflow收集起来组成队列,在一定时间后flush队列,将多个reflow的变为一次reflow,可以多跑几款浏览器看看。

    虚拟dom

    以vue为例,虚拟dom之所以能提升性能,核心思想就是将真实dom映射为js的object,通过捕获收集object的差异,将对dom的操作一次性压入DocumentFragment,等待下一次事件循环再进行reflow,这样就有效减少了dom的操作次数,提升了渲染效率。

    相关文章

      网友评论

        本文标题:虚拟dom如何提升性能?

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