zoukankan      html  css  js  c++  java
  • Virtual DOM 系列一:认识虚拟DOM

    1. 什么是Virtual DOM?

    Virtual DOM(虚拟DOM)是指用JS模拟DOM结构。本质上来讲VD是一个JS对象,并且至少包含三个属性:tag(html标签),props(标签的属性,如class),children(子元素对象)。

    <div class="setting-menu">
      <ul>
        <li>Picture</li>
        <li>Sound</li>
        <li>Time</li>
      </ul>
    </div   

    用JS模拟上面这段DOM结构:

    {
        tag: 'div',
        props: {class: 'setting-menu'},
        children: [
            {
                tag: 'ul',
                props: {},
                child: [
                    {
                        tag: 'li',
                        props: {},
                        children:['Picture']
                    },
                    {
                        tag: 'li',
                        props: {},
                        children:['Sound']
                    },
                    {
                        tag: 'li',
                        props: {},
                        children:['Time']
                    }
                ]
            }
        ]
    }
    

    2. 为什么需要Virtual DOM?

    知其然,知其所以然。我们知道了什么是虚拟DOM之后,还得需要知道为什么需要他?

    首先,我们先达成一个共识:"JS操作DOM的代价是昂贵的,会引起回流和重绘,严重影响性能"。

    现在有一个需求,上诉DOM结构需要支持修改,增加,删除?

    1. 最简单的做法:通过JS操作DOM。该方法的缺点:随这应用的复杂度提升,代码变的难以维护,且性能不好,每次dom操作可能都会引起浏览器的回流和重绘。

    2. MVC模式。之后研究出了MVC,MVP模式,但这种模式只是从代码组织的方式来降低维护难度,并没用改变JS操作DOM的本质。

    3. MVVM模式,只要在模版中声明视图组件是和什么状态进行绑定的,双向绑定引擎就会在状态

    更新的时候自动更新视图,MVVM 可以能很好的降低维护状态以及减少视图的复杂程度。

    还有一个非常直观的方法,可以大大降低视图更新的操作。一旦状态发生了变化,就用模版引擎重新渲染整个视图,然后用新的视图更换掉旧的视图。就像上面的表格,当用户点击的时,还是在 JS 里面更新状态,但是页面更新就不用手动操作 DOM 了,直接把整个表格用模版引擎重新渲染一遍,然后设置一下 innerHTML 。那么这个方法会有个很大的问题,会导致 DOM 操作变慢,因为任何的状态变更都要重新构造整个 DOM,性价比很低。对于局部的小视图的更新,这样没有问题(backbone就是这么干的)。但对于大型视图,需要更新页面较多局部视图时,这样的做法就非常不

    可取。

    使用Jquery模拟:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      <div id="container"></div>
      <button id="btn-change">change</button>
    
      <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
      <script type="text/javascript">
        var data = [{
          name: "张三",
          age: 24,
          address: "深圳"
        }, {
          name: "张三",
          age: 24,
          address: "深圳"
        }, {
          name: "张三",
          age: 24,
          address: "深圳"
        }];
        
        /**
        * 渲染页面
        *
        */
        function render(data) {
          // first step clear container
          $('#container').html('');
    
          // 拼接ul
          var uldom = document.createElement('ul');
          for(var i = 0; i < data.length; i++) {
            var lidom = document.createElement('li');
            lidom.append(`name: ${data[i].name}, age: ${data[i].age}, address: ${data[i].address}`);
            uldom.appendChild(lidom);
          }
    
          //渲染页面 放到最后 一次渲染
          $('#container').append(uldom);
        }
        
        $('#btn-change').click(function () {
          data[1].name = '李四';
          data[2].name = '王五';
    
          //修改后重新渲染
          render(data);
        })
        render(data); //初始化页面渲染
    
      </script>
    </body>
    </html>
    

      

     

    既然JS操作DOM很慢,而操作JS对象非常快,就可以用 JavaScript 对象表示的树结构来构建一个真正的 DOM 。当状态变更时,重新渲染这个 JavaScript 的对象结构,实现视图的变更,结构根据变更的地方重新渲染这就是Virtual DOM 算法。

    通过VD的比较,我们可以将多个操作合并成一个批量的操作,并且只更新有差异的部分,从而减少dom重排的次数,进而缩短了生成渲染树和绘制所花的时间。

  • 相关阅读:
    spark机器学习从0到1特征抽取–Word2Vec(十四)
    spark机器学习从0到1特征抽取–CountVectorizer(十三)
    spark机器学习从0到1特征提取 TF-IDF(十二)
    spark机器学习从0到1机器学习工作流 (十一)
    vant ui中area组件踩坑记录
    免费CDN:jsDelivr+Github 使用方法
    使用vue-quill-editor实现富文本编辑器
    数组添加元素到特定位置
    scoop——强大的Windows命令行包管理工具
    radio单选框样式
  • 原文地址:https://www.cnblogs.com/charliePU/p/10791102.html
Copyright © 2011-2022 走看看