虚拟DOM和diff算法

虚拟DOM是在DOM的基础上在内存建立了一个抽象层,对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟DOM,最后再批量同步到DOM中

传统DOM操作和虚拟DOM操作的区别:

【传统DOM操作(例如:innerHtml)】:render html => 重建所有DOM元素

    **传统DOM操作(例如:innerHtml)通过重建所有DOM元素**

【虚拟DOM】:render 虚拟DOM + diff算法 => 更新必要的DOM元素

    **虚拟DOM +  diff算法  是  更新必要的DOM元素**

虚拟DOM因为是纯粹的JS对象,所以操作它会很高效,但是虚拟DOM的变更最终会转换成DOM操作,为了实现高效的DOM操作,一套高效的虚拟DOM diff算法显得很有必要。

在这里插入图片描述

简单的duff

简单的diff算法可以这样设计:

        1. 逐个遍历DOM树的所有节点,找到它在原始DOM树中的位置
        2. 找到了就移动对应的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。
        3. 遍历完成之后如果原始DOM树中还有没处理过的节点,则说明这些节点在新DOM树中被删除了,删除它们即可。

*仔细思考一下,几乎每一步都要做移动DOM的操作,这在DOM整体结构变化不大时的开销是很大的,实际上DOM变化不大的情况现实中经常发生,很多时候我们只需要变更某个节点的文本而已。

接下来我们看一下Vue的diff实现
Vue不断对vnode进行处理同时移动指针直到其中任意一对起点和终点相遇。处理过的节点Vue会在oldVdom和newVdom中同时将它标记为已处理。

Vue通过以下措施来提升diff的性能:

1.优先处理特殊场景,特殊场景一般有:

    (1)、头部的同类型节点、尾部的同类型节点
                就是这类节点更新前后位置没有发生变化,所以不用移动它们对应的DOM
     (2)、头尾/尾头的同类型节点
                这类节点位置很明确,不需要再花心思查找,直接移动DOM就好

2.“原地复用”

     例如:2个不同的div,在DOM上它们是不一样的,但是它们又属于同类节点,如果是同类节点,那么Vue会直接复用这个DOM,这样的好处是不需要移动DOM。 假如10个节点都是div,那么整个diff过程中就没有移动DOM的操作了。

先看一张整体视图,整个diff分两部分:

在这里插入图片描述

 (1)、第一部分是一个循环,循环内部是一个分支逻辑,每次循环只会进入其中的一个分支,
        每次循环会处理一个节点,处理之后将节点标记为已处理(oldVdom和newVdom都要进行标记,如果节点只出现在其中某一个vdom中,则另一个vdom中不需要进行标记),标记的方法有2种,当节点正好在vdom的指针处,移动指针将它排除到未处理列表之外即可,否则就要采用其他方法,Vue的做法是将节点设置为undefined。

(2)、循环结束之后,可能newVdom或者oldVdom中还有未处理的节点,如果是新的Vdom中有未处理节点,则这些节点是新增节点,做新增处理。如果是oldVdom中有这类节点,则这些是需要删除的节点,相应在DOM树中删除之

        这个过程是逐步找到更新前后vdom的差异,然后将差异反应到DOM树上(也就是patch),这里特别要提一下的是 ,Vue的DOM树是即时更新的,并不是打包所有修改最后一起操作DOM(React则是将更新放入队列后集中处理),朋友们会问这样做性能很差吧?实际上现代浏览器对这样的DOM操作做了优化,并没有特别大的差别。

diff算法:

优点:最终表现在DOM上的修改只是部分的变更,可以保证高效的渲染,提高网页的性能
缺点:首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHtml慢一点

以下是我个人理解的虚拟DOM以及dIff算法的实现过程:
1. 用 javaSvript 对象结构表示 DOM 树的结构 ; 然后用这个树构建一个真正的 DOM 树,查到页面文档当中,也就是渲染到页面上
2. 当状态变更的时候,重新构造一颗新的对象树,然后用新的树和原来旧的树进行比较,记录两颗书的差异
3. 把2中比较出的差异应用到步骤1中构造的真正的DOM树上,更新视图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值