当前位置: 首页 > news >正文

react的diff算法

这个算法用来比较虚拟dom和真实dom,从而最小化真实dom的更新

本质上是对两颗Fiber树的对比
(在Vue中是对旧VDOM树与新VDOM树的对比)

在不剪枝的情况下,时间复杂度接近O(n^3)

基于最长公共子序列 (LCS) 的朴素计算为O(n2),加上需要递归比较子节点,时间复杂度来到O(n3)

diff的限制:

  1. 只进行同层级比较
  2. 新旧节点的type不同直接删除旧节点,创建新节点
  3. 通过 key 来复用节点

三个层级的比较策略

  1. 第一步剪枝,Tree层级的比较
    每次递归开始的第一步,比较两棵树的根节点,不一样直接销毁整棵树重建
  2. Component层级
    type同 => 保持组件实例不变只更新props,然后进入组件的render结果进行Element层级的比较
    type不同 => 销毁重建
  3. Element层级
    type同 => 更新属性
    type不同 => 销毁重建

diff算法

根据fiber节点的child类型判断是单节点diff还是多节点diff,仅当child类型为数组时进行多节点diff

1. 单节点diff

key同 且 type不同 => 执行 deleteRemainingChildren 将 child 及其兄弟 fiber 都标记删除。
key不同 => 将child标记删除,然后遍历兄弟fiber

在 React 中,一个 Fiber 节点(即组件实例)的状态(State)和 Hooks(如 useState, useEffect)是严格绑定在它的 type 上的。让一个不再渲染的旧组件 Fiber 保持 Hooks 激活状态是错误的,会导致内存泄漏和不可预测的行为,必须立即销毁重建。

2.多节点diff

两轮遍历

1. 第一轮

key同 type同可复用
key 不同导致不可复用,立即跳出整个遍历,第一轮遍历结束。
key 相同 而type 不同导致不可复用,会将 oldFiber 标记为 DELETION,并继续遍历
newChildren和oldFiber其一遍历完成就跳出

2. 第二轮

  1. newChildren 与 oldFiber 同时遍历完
    只需在第一轮遍历进行组件更新。此时 Diff 结束。

  2. newChildren 没遍历完,oldFiber 遍历完
    遍历剩下的 newChildren 为生成的 fiber 依次标记 Placement。

  3. newChildren 遍历完,oldFiber 没遍历完
    遍历剩下的 oldFiber,依次标记 Deletion。

  4. newChildren 与 oldFiber 都没遍历完
    处理移动的节点

react会把剩余的旧 Fiber 及其在旧列表中的索引存入一个 Map 中
每个新节点有两个index,oldIndex 和 maxIndex,
oldIndex:新节点在 Map 中查找对应的旧 Fiber,得到它在旧列表中的原始索引。
maxIndex: 记录当前遇到的所有旧节点中的最大原始索引。

当 oldIndex>maxIndex 时,将 oldIndex 的值赋值给 maxIndex
当 oldIndex=maxIndex 时,不操作
当 oldIndex<maxIndex 时,将当前节点移动到 index 的位置

http://www.hskmm.com/?act=detail&tid=38369

相关文章:

  • LLM学习记录DAY11
  • ABP - 当前用户 [ICurrentUser、CurrentUser]
  • 轮次检测模型 VoTurn-80M 开源,多模态融合架构;OpenAI 收购桌面助手 Sky:实时识别屏幕自然语言交互丨日报
  • 第4天(中等题 滑动窗口、哈希表)
  • 幂函数
  • ABP - 依赖注入和属性注入
  • SAP维护汇率的关键Tcode
  • ABP vNext 框架功能模块 - 动态API(Dynamic API)
  • ABP vNext 框架功能模块 - 模块化(Modularity)
  • Devolutions Server权限提升漏洞分析与修复指南
  • AI股票预测分析报告 - 2025年10月24日 - 20:08:50
  • 题解:P14299 [JOI2023 预选赛 R2] 填充 / Painting
  • str.endswith() 类似的方法
  • 在 Astro 博客中优雅使用 51.la 统计数据
  • 2025.10.24博客
  • cgroup
  • 设计模式:代码界的 “光之巨人” 养成指南(附 C++ 实战)
  • 深度剖析OpenHarmony AI Engine:开发板端侧大模型推理插件机制全链路拆解 - 实践
  • Linux下的拼音输入法 (3)
  • P2606 [ZJOI2010] 排列计数 分析
  • 分治算法乱讲
  • 电动三轮车后桥改造添加动能回收实现无限续航的可能。
  • Claude Code配置记录
  • 视频融合平台EasyCVR在智慧工地中的应用:构建安全、智能、高效的“云上工地” - 实践
  • 股票操作统计分析报告 - 2025年10月24日
  • [HZOI] CSP-S模拟37 赛后总结
  • 24
  • 数字人:数字人公司排行榜及技术深度剖析
  • 【同余最短路】学习笔记
  • 数字人:数字人公司深度解析与未来展望