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

什么是diff算法

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

什么虚拟DOM

  • 虚拟DOM是表示真是DOM的JS对象
css 复制代码
// 结构为
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对象如何进行差异处比较

如何进行子元素内容比较

  • 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值 去比较 新虚拟DOM 的key值 ,如果key相同则复用 ,并移动到新虚拟DOM 的位置
比对有相同的内容
  1. 首先 oldS 和newS做比对,没有比对成功
  2. 接着 oldS 和 newE 做比对,比对成功,更新真实DOM ,将比对成功的结果按照 newVnode 节点中展示的内容,移动节点
  3. 因为上一次比对成功,oldVnode 比对成功,oldVnode 的 开始节点 往左侧移动,然后再去跟 newVnode 的start 节点去做比对,如果比对成功,那么真实DOM 就会根据 newVnode的节点位置 进行更新
  4. 因为上一次 oldStart 和 newStart 比对成功,所以两者都会向左移动一下,接着开始第三次比对,oldStart 和newStart 比对成功,因为newVnode 中的 被比对的内容位置是第二位,所以真实DOM中的内容位置也需要调整
  5. 接着,oldVnode 和 newVnode 的 start节点 位置在向左侧移动,因为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操作,从而进一步提供性能

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

相关推荐
@PHARAOH18 分钟前
WHAT - Vite 8(Rolldown 底层构建引擎升级)
前端·架构
阿Q的AI笔记21 分钟前
从ReAct到GRPO、从OpenHands到SWE-agent:Agent完整知识体系全拆解
前端·react.js·前端框架
计算机魔术师26 分钟前
从六个月路线图到JIT规划:代码评审不只是审代码
前端
迅猛龙办公室32 分钟前
Python实现PM空气质量提醒
服务器·前端·python
鬼手点金2 小时前
模型即 Agent:当模型本身成为产品
开发语言·前端·人工智能·python·机器学习
kiracrimson2 小时前
npm 入门:包管理器、依赖与 npx
前端·npm·node.js
ShineWinsu2 小时前
对于JavaScript:初识JavaScript以及输入输出
java·开发语言·前端·javascript·css·面试·html
鲤鱼_5992 小时前
教培机构一体化运营管理系统操作手册
前端
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 3 章 Fiber 架构与双缓冲
前端·react.js·开源