当前位置: 首页 > 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.zskr.cn/news/29689.html

相关文章:

  • LLM学习记录DAY11
  • ABP - 依赖注入和属性注入
  • ABP vNext 框架功能模块 - 依赖注入和属性注入
  • 幂函数
  • ABP vNext 框架功能模块 - 动态API(Dynamic API)[RemoteServiceAttribute | DynamicApiControllerBuilder]
  • AI股票预测分析报告 - 2025年10月24日 - 20:08:50
  • str.endswith() 类似的方法
  • cgroup
  • 数字人:数字人公司排行榜及技术深度剖析
  • 【同余最短路】学习笔记
  • 数字人:数字人公司深度解析与未来展望
  • CSP/NOIP 复习:单调栈
  • 数字人企业:数字人公司排行榜深度解析
  • 数字人公司:数字人新趋势技术驱动与市场前景解析
  • WPF 深入系列.2.布局环境.布局控件.Grid
  • 冬日绘板 2026 珂朵莉计划 如何获取 Token
  • 数字人:怎么选择数字人实力公司
  • Asterix cat-062 ,航班号字段的编码解码
  • AI优化企业:GEO公司技术先驱
  • 题3
  • 吴恩达深度学习课程一:神经网络和深度学习 第四周:深度神经网络的关键概念
  • 第171-172天:代理通讯篇无外网或不可达SockS全协议规则配置C2正反向上线解决方案
  • SpringBoot整合缓存1-Ehcache
  • 如何在一台 Linux 机器上管理不同版本的 CMake
  • 90 天打造可持续交付:12 条 DevOps 实践要点与避坑
  • Linux基础——iptables常规操作
  • 题解:P8930 「TERRA-OI R1」神,不惧死亡
  • 大数据案例 -2025/10/24
  • 详细介绍:记一次达梦数据库的查询异常
  • 从价值直觉到价值理性:AI元人文演进路径解读