Vue2中、Vue3中的diff算法的区别是什么?

231 阅读4分钟

什么是diff算法

根据B站中,以及查阅资料了解到的vue中的 diff算法 思路还有想法,记录一次,因为没有对于写博客相关而言是纯新手,所以求大家轻喷

什么虚拟DOM

  • 虚拟DOM是表示真是DOM的JS对象
// 结构为
let Vbode = {
    tagName:'div'
    props:{
    'class':'container',
    }
    children:[
        {
            tagName:'p',
            props:{
                "class":'item'
            },
            text:'文字内容'
        },
        {
            tagName:'strong',
            props:{
                "class":'item'
            },
            text:'文字内容'
        }
    ]
}
​
// 解释
tagName     标签名
props       标签属性
text        文本属性
children    子属性

diff算法用来干嘛

一段真实的DOM数据 , 对应一段虚拟的DOM对象 , 如果我们修改了 真实DOM 那么就会产生一段新的虚拟DOM对象,新旧两个虚拟对象是存在差异的,如果能快速找到差异,就能最小化的去更新视图

在vue内部专门准备了一套算法来进行新久值比对 ,这个比较方法就是diff算法 ,它的作用就是赵处差异,最小化更新视图

虚拟DOM的JS对象如何进行差异处比较

image-20231206130903008.png

如何进行子元素内容比较

  • oldvnode 有children属性
  • newvnode 有childrend 属性
  • 按照同级进行比对
  • 同级比对的方法 采用的是 首尾指针法

vue2中的首尾指针法

自底向上、深度优先

比对不同的版本
  1. 不管新旧的虚拟DOM节点都是有 首节点 start尾节点 end

    1. 首先 oldS首节点 会去跟 newS 首节点去比对,
    2. 如果没有比对成功,旧虚拟节点(oldS首节点),会去和新虚拟节点(newE尾节点) ,
    3. 如果依旧没有比对成功 ,旧虚拟DOM(oldE尾节点) 会去跟 新虚拟DOM(newS首节点)去做比对
    4. 如果依旧没有比对成功,旧虚拟DOM(oldE尾节点) 会去跟新虚拟DOM(newE尾节点)去做比对
  • 依次比较,当比较成功后退出当前比较
  • 渲染结果以 newVnode 为准
  • 每次比较成功后 start 点end点 向中间靠拢
  • 新旧节点中有个start点 跑到end点右侧时终止比较
  • 如果都匹配不到(首尾指针法),则旧虚拟DOM key值去比较 新虚拟DOMkey值如果key相同则复用,并移动到新虚拟DOM 的位置
比对有相同的内容
  1. 首先 oldSnewS做比对,没有比对成功
  2. 接着 oldSnewE做比对,比对成功,更新真实DOM,将比对成功的结果按照 newVnode 节点中展示的内容,移动节点
  3. 因为上一次比对成功,oldVnode比对成功,oldVnode开始节点 往左侧移动,然后再去跟 newVnodestart节点去做比对,如果比对成功,那么真实DOM就会根据 newVnode的节点位置 进行更新
  4. 因为上一次 oldStartnewStart 比对成功,所以两者都会向左移动一下,接着开始第三次比对,oldStartnewStart比对成功,因为newVnode中的 被比对的内容位置是第二位,所以真实DOM中的内容位置也需要调整
  5. 接着,oldVnodenewVnodestart节点位置在向左侧移动,因为oldVnode 的 内容长度小于 newVnode 的长度,所以此时新旧虚拟DOM内容比对结束,此时会将newVnode中没有被比对的内容按照坐标放在真实DOM
  6. 没有新旧虚拟节点比对结束后,newVnode中的长度小于oldVnode的长度,则需要将真实DOM中的newVnode没有的内容进行删除

vue2、vue3的diff算法有什么区别

  • Vue3中,引入一种称为 静态标记的dff算法。在编译阶段,Vue会对模板进行静态分析,并给静态节点添加一个标记。在更新过程中,Vue会跳过这些静态节点的比较,只对非静态节点进行diff操作,这个优化可以大大减少diff算法的时间复杂度,提高更新性能
  • Vue2中,vue实用了一种称为双指针算法的diff策略。当进行更新操作时,Vue会逐层比较新旧虚拟DOM树,通过比较虚拟DOM节点的标签名,key 等属性来判断节点是否相同,以此决定是否需要更新该节点以及其子节点。这个算法的时间复杂度时 O(n) , 其中n时节点数量

Vue3中组件级别的diff策略

这个是vue3的优化的内容

在Vue2中,每次内容更新都会对整个组件进行diff操作无论组件内部是否有变化,这么操作是非常损耗性能的。

而在 vue3中, Vue会跟踪每个组件的依赖,只对发生变化的组件进行 diff操作,从而进一步提供性能

在此优化下大规模应用、复杂组件等等的场景下表现更好