vue diff 和 react diff区别,面试必备

面试的时候经常会有面试官问到,vue diff 和 react diff,如果你vue 和 react 都会,那么恭喜可能会中枪,面试官会让你先说vue2和vue3的数据双向绑定,数据劫持的不同,再说vue的key的作用,引出vue的diff,再到react的diff,在说出他们的区别,在给你一个例子,各自怎么移动的

⚙️ 1. 节点比较策略:双端 vs 单向

  • Vue(双端比较)
    采用首尾双指针 同时向中间移动,优先对比头部/尾部节点(头-头、尾-尾、头-尾、尾-头)。若匹配成功则复用节点并移动指针;若无匹配,则基于 最长递增子序列(LIS) 算法处理中间节点的移动。
    优势 :对节点位置变化(如列表重排)更高效。例如,将末尾节点移到开头时,Vue 只需移动一个节点。
  • React(单向遍历)
    采用从左到右的单指针 遍历,按顺序对比新旧节点。依赖 keylastIndex 判断复用:若新节点 index < lastIndex,则标记移动。
    劣势 :末尾节点移到开头时,需将前方所有节点右移,导致 O(n) 移动开销

💡 示例场景 :列表 [A, B, C, D][D, A, B, C]

  • Vue:移动 D 到开头(1 次操作)。
  • React:将 A/B/C 依次右移(3 次操作)。

🧩 2. 节点复用逻辑:属性敏感性 vs 类型优先

  • Vue
    若节点标签类型相同但关键属性(如 className)不同 ,视为不同节点,删除并重建 。例如 <div class="a"> 变为 <div class="b"> 会触发重建。
    原因:Vue 认为属性变化可能影响布局,需彻底更新。
  • React
    只要标签类型和 key 相同 ,仅更新变化的属性 (如修改 className),不重建节点。
    优势:减少 DOM 操作,但对样式变化敏感的场景可能需手动优化。

3. 更新机制:同步 vs 批量

  • Vue
    在 Diff 过程中同步更新真实 DOM (如调用 insertBefore),最后处理删除。
    影响:更早呈现变化,但频繁更新可能引发布局抖动。
  • React
    先收集变更形成 effect list ,再批量更新 DOM (先删除 → 更新 → 插入)。结合 Fiber 架构支持中断/恢复更新,适合高优先级任务。

🚀 4. 优化策略:编译时 vs 运行时

  • Vue 3 的编译时优化

    • 静态提升(Hoisting) :编译阶段标记静态节点,跳过运行时 Diff。
    • Patch Flags:动态节点标记变化类型(如文本/属性),仅对比标记部分。
    • LIS 算法:最小化节点移动次数。
  • React 的运行时优化

    • Fiber 时间分片:将 Diff 拆分为可中断的微任务,避免阻塞主线程。
    • 手动优化 :依赖开发者通过 shouldComponentUpdateReact.memo 避免无效更新。

🔍 5. 核心差异总结

下表对比两者根本区别:

维度 Vue React
比较方向 双端(两端→中间) 单向(左→右)
节点复用 属性变化则重建 同类型节点仅更新属性
列表移动优化 LIS 算法,移动次数最少 基于 index/lastIndex,移动开销更大
DOM 更新时机 Diff 中同步更新 批量更新(effect list)
性能侧重 复杂列表动态更新 静态结构+手动优化

💎 根本结论

Vue 和 React Diff 算法的最根本区别 在于:

👉 Vue 通过双端比较 + LIS 算法 + 编译时优化,优先减少节点移动次数,尤其擅长动态列表更新

👉 React 依赖单向遍历 + Fiber 分片,强调批量更新和开发者手动控制,适合结构稳定的应用

选择建议:

  • 高频列表操作(如拖拽排序)选 Vue
  • 需精细控制更新逻辑或集成复杂状态管理选 React

如果你觉得上面太简洁,同样也可以这样说

首先,两者有一些共同点:都只进行同级比较而不跨层级,都使用 key 作为唯一标识来复用节点。最根本的区别在于它们的比较策略:React 使用单向遍历(从左到右),而 Vue 使用双端比较(从两端向中间)。这个差异导致了它们在处理节点移动时的不同性能表现。

另外,一个典型场景:

当最后一个节点被移动到列表开头时,React 会将前面的所有节点都向后移动,而 Vue 只会移动这一个节点。这表明 Vue 在处理节点位置变化时更高效。

还有一个重要区别是属性变化的处理:当节点元素类型相同但类名不同时,Vue 认为是不同类型元素会删除重建 ,而 React 认为是同类型节点只修改属性。

在优化策略上也有差异:Vue 3 引入了编译时优化(静态提升、Patch Flags),而 React 依赖 Fiber 架构和手动优化(如 shouldComponentUpdate。

更新机制也不同:Vue 在 diff 过程中同步更新真实 DOM ,而 React 先收集变更形成 effect list 再批量更新 。

对于列表处理,Vue 3 使用了最长递增子序列(LIS)算法来最小化节点移动 ,而 React 使用基于 index 和 lastIndex 的简单比较 。

旧节点abcd 新节点是 bcaf , vue 和 react 分别怎么diff的

Vue 的 Diff 过程(双端比较 + LIS)

  1. 初始化指针
    旧: [a, b, c, d] → 头指针=0(a),尾指针=3(d)
    新: [b, c, a, f] → 头指针=0(b),尾指针=3(f)

  2. 双端比较

    • 头头对比:a ≠ b → ❌
    • 尾尾对比:d ≠ f → ❌
    • 头尾对比:a ≠ f → ❌
    • 尾头对比:d ≠ b → ❌
  3. 非理想模式 (建立 key-index 映射):

    新节点映射:{b:0, c:1, a:2, f:3}

    • 查找新头节点 b
      旧索引=1 → 移动 b 到旧头指针前(a 之前)
      标记旧位置1为 undefined,新头指针右移 → 新: [c, a, f]
    • 查找新头节点 c
      旧索引=2 → 移动 c 到旧头指针前(a 之前)
      标记旧位置2为 undefined,新头指针右移 → 新: [a, f]
    • 头头对比 :a = a → 复用,旧头指针右移 → 旧: [d],新头指针右移 → 新: [f]
    • 头头对比:d ≠ f → ❌
    • 查找新头节点 f
      旧索引不存在 → 创建 f 并插入旧头指针前(d 之前)
  4. 清理旧节点

    删除未处理的旧节点 d

  5. 最终操作

js 复制代码
移动节点: b, c (2次)
创建节点: f (1次)
删除节点: d (1次)

React 的 Diff 过程(单向遍历)

  1. 初始化映射

    创建旧节点 key-index 映射:{a:0, b:1, c:2, d:3}

    初始化 lastIndex = 0(记录当前已复用的最大旧索引)

  2. 遍历新节点

    • 新节点 b(key=b)

      • 旧索引 = 1(lastIndex=0
      • 1 > 0 → 复用旧节点 b,不移动
      • 更新 lastIndex = max(0,1) = 1
    • 新节点 c(key=c)

      • 旧索引 = 2(lastIndex=1
      • 2 > 1 → 复用旧节点 c,不移动
      • 更新 lastIndex = max(1,2) = 2
    • 新节点 a(key=a)

      • 旧索引 = 0(lastIndex=2
      • 0 < 2 → 移动节点 a 到当前位置(c 之后)
      • 不更新 lastIndex(仍为 2)
    • 新节点 f(key=f)

      • 旧索引不存在 → 创建新节点 f
  3. 清理旧节点

    删除未复用的旧节点 d

  4. 最终操作

makefile 复制代码
移动节点: a (1次)
创建节点: f (1次)
删除节点: d (1次)

💡 场景分析:

  • React 优势 :当节点从头部移到尾部时(如 a 从开头移到末尾),只需移动 1 次。
  • Vue 优势 :当节点整体轮转 时(如 [a,b,c,d][d,a,b,c]),Vue 只需移动 1 次(d),React 需移动 3 次。
相关推荐
天才熊猫君1 小时前
npm 和 pnpm 的一些理解
前端
飞飞飞仔1 小时前
从 Cursor AI 到 Claude Code AI:我的辅助编程转型之路
前端
qb1 小时前
vue3.5.18源码:调试方式
前端·vue.js·架构
Spider_Man1 小时前
缓存策略大乱斗:让你的页面快到飞起!
前端·http·node.js
前端老鹰1 小时前
CSS overscroll-behavior:解决滚动穿透的 “边界控制” 专家
前端·css·html
一叶怎知秋2 小时前
【openlayers框架学习】九:openlayers中的交互类(select和draw)
前端·javascript·笔记·学习·交互
allenlluo2 小时前
浅谈Web Components
前端·javascript
Mintopia2 小时前
把猫咪装进 public/ 文件夹:Next.js 静态资源管理的魔幻漂流
前端·javascript·next.js
Spider_Man2 小时前
预览一开,灵魂出窍!低代码平台的魔法剧场大揭秘🎩✨
前端·低代码·typescript
xianxin_2 小时前
HTML 代码编写规范
前端