最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 虚拟DOM与DOM diff

    正文概述 掘金(Zeroy)   2021-03-20   592

    本文主要包含以下内容:

    一、 虚拟DOM

    1. 虚拟DOM是什么
    2. 虚拟DOM的优点
    3. 虚拟DOM的缺点

    二、 DOM diff

    1. DOM diff是什么
    2. DOM diff的大致逻辑
    3. DOM diff如何进行比较
    4. 解决DOM diff存在的问题

    一、虚拟DOM

    1. 虚拟DOM是什么?

    1.1 DOM回顾

    MDN对其解释如下:

    事实上为了让网页实现各种各样的效果,浏览器给window添加了一个document对象,我们将网页抽象成一个document对象,通过这个document对象操作整个页面的所有的节点。上述模型Document Object Model 也就是DOM

    我们每一次使用 js 操作 DOM,或者 DOM 每一次细微的改变,都会引发页面的重绘(paint)重排(layout),这也是我们经常所说的“DOM操作慢”的根本原因

    1.2 虚拟DOM

    虚拟DOM,也叫VDOM,一个能代表DOM树的对象,通常含有标签名、标签上的属性、事件监听和子元素以及其他属性。其本质是一个JS对象.它是仅存于内存中的DOM,因为还未展示到页面中,所以称为VDOM。

    举个随处可见的例子:

    var a = document.createElement("div");  //这就是VDOM
    

    那么如何让VDOM变成真实的DOM呢?

    -简单,只需将节点append到页面中:

    var a = document.createElement("div");
    document.body.append(a);   // 此时body内就会创建一个div标签,真实DOM
    
    • Vue、React中的虚拟DOM

      • Vue
      h('div', {
          class: 'red',
          on: {
              click: () => {}
          },
      }, [h('span', {}, 'span1'), h('span', {}, 'span2')])
      
      
      • React
      createElement('div', {className:'red', onClick: () => {}}, [
          createElement('span', {}, 'span1'),
          createElement('span', {}, 'span2')
        ]
      )
      

    2.虚拟DOM的优点

    2.1 减少DOM操作

    • 减少DOM操作的次数,虚拟DOM可以将多次操作合并为一次操作,例如在div中添加1000个甚至更多的节点,常规的方法是一个接一个的操作的。

    • 减少DOM操作的范围,虚拟DOM借助DOM diff(后文会说)可以把多余的操作去掉,例如添加1000个节点,实际上只有10个节点是新增的,DOM diff会将其简化操作,而不是重绘。

    2.2 能够跨平台渲染

    虚拟DOM不仅能够变成DOM,还可以变成小程序、ios应用、安卓应用,因为其本质是一个JS对象。

    3. 虚拟DOM的缺点

    需要通过额外的创建函数,如React需要creatElement,Vue 需要h函数等,但是可以通过JSX语法(React)Vue-loader(Vue)来解决。如下:

    **Vue Template**
    通过`Vue-loader`转化为`h`形式
    <div class="red" @click="fn">
     <span>span1</span>
     <span>span2</span>
     </div>
     -----------------------------------------------
    **React JSX**
    通过`bable`转化`creatElemet`形式
     <div className="red" onClick={fn}>
     <span>span1</span>
     <span>span2</span>
     </div>
    

    二、DOM diff

    1. 什么是DOM diff

    DOM diff两个虚拟DOM树对比的算法,diff 算法仅在两个树的同级的虚拟节点之间做比较,递归地进行比较,最终实现整个 DOM 树的更新。

    DOM diff本质上就是一个函数,我们称之为patch函数。有两个参数,分别是旧的虚拟DOM和新的虚拟DOM

    patches=patch(oldVnode,newVnode)
    

    patches就是要运行的DOM操作,类似于:

    [
      {type: 'INSERT', vNode: ... },
      {type: 'TEXT',  vNode: ... },
      {type: 'PROPS', propsPatch: [...]}
    ]
    

    2. DOM diff的大致逻辑

    • tree diff(层级比较)

      1.将新旧两棵树逐层对比,找出哪些节点需要更新。

      2.如果节点是组件就看Component diff

      3.如果节点是标签就看Element diff

    • Component diff

      1.如果节点是组件,就先看组件类型,类型不同直接替换(删除旧的),类型相同则更新属性。

      2.然后深入组件做 tree diff

    • Element diff

      1.如果节点是原生标签,则看标签名,标签名不同直接替换,相同则更新属性。

      2.然后进入标签后代做tree diff

    3.DOM diff如何进行比较

    如下代码:

    <div :class="x">
        <span v-if="y">{string1}</span>
        <span>{string2}</span>
    </div>
    

    以上代码树的结构图可用下图表示: 虚拟DOM与DOM diff

    我们默认所有节点都是可变化的,假定div中的class变成了red,于是patch函数就会开始遍历并进行比较。

    虚拟DOM与DOM diff

    下面我们再变化,将第一个span删除。

    虚拟DOM与DOM diff 计算机会认为是第一个span更新了,第二个span删除了!这就是DOM diff所存在的问题。

    4. 解决DOM diff存在的问题

    那么有什么办法可以解决DOM diff存在的问题呢?答案就是使用key(react跟vue都需要使用单独的key,这个key在同属于一个父节点的各兄弟节点上需要不同。)

    如下:

    //React JSX语法
    <div>
    {[{id:1,value:1},{id:2,value:2},{id:3,value:3}].map((v)=>{
       return <span key={v.id}/>
    })}
    </div>
    

    起源地下载网 » 虚拟DOM与DOM diff

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元