react中的filble架构和diffes算法如何实现的

一、先给面试官的"王炸开场白"

你可以先来这一句 👇

React Fiber 是为了解决旧 Diff 递归不可中断的问题,引入的可中断、可优先级调度的架构;Diff 算法本身没变,但执行方式变了。

⚠️ 这一句,直接把你和"只背概念的人"区分开。


二、为什么 React 要引入 Fiber?

1️⃣ 旧架构的问题(Stack Reconciler)

React 16 之前:

sql 复制代码
更新 → 递归 diff → 一口气算完 → commit

致命问题

  • 不可中断
  • ❌ 大组件树会卡主线程
  • ❌ 无法区分优先级(动画、输入)

👉 用户体验:掉帧、卡顿


2️⃣ Fiber 解决了什么?

一句话总结 👇

把"递归不可中断" → 拆成"可中断的任务单元"


三、Fiber 是什么?(一定要讲清楚)

1️⃣ Fiber 本质不是算法,是数据结构

kotlin 复制代码
interface Fiber {
  type
  key
  stateNode

  child
  sibling
  return

  pendingProps
  memoizedProps
  memoizedState

  flags
}

核心点

  • 每一个组件 = 一个 Fiber 节点
  • Fiber 是 链表结构,不是树递归

2️⃣ Fiber 结构长什么样?

yaml 复制代码
parent
  |
 child ------ sibling ------ sibling

👉 用 child / sibling / return 模拟树

为什么不用数组?

  • 链表更容易拆分、暂停、恢复

四、Fiber 架构是怎么"跑"起来的?

React 更新分两大阶段(必考)

sql 复制代码
Render 阶段(可中断)
Commit 阶段(不可中断)

1️⃣ Render 阶段(核心)

做什么?

  • Diff
  • 生成 Fiber 树
  • 标记副作用(flags)

特点:

  • ✅ 可中断
  • ✅ 可恢复
  • ❌ 不操作 DOM
lua 复制代码
workLoop
  ↓
performUnitOfWork
  ↓
next Fiber

2️⃣ Commit 阶段

做什么?

  • 操作 DOM
  • 执行 useEffect

特点:

  • ❌ 不可中断
  • ✅ 很快

3️⃣ 面试话术

Fiber 通过把 Render 阶段拆成小任务,配合浏览器空闲时间执行,实现了时间分片。


五、什么是时间分片(Time Slicing)?

核心 API

复制代码
requestIdleCallback

React 内部思想:

php 复制代码
while (有任务 && 有空闲时间) {
  执行一个 Fiber
}

👉 不卡 UI 的关键


六、Diff 算法到底是怎么做的?

⚠️ 重点来了:
Diff 算法思想没变,执行模型变了


React Diff 的三大假设(必背)

1️⃣ 不同类型节点,直接删

css 复制代码
<div /> → <span />

👉 不复用,整棵子树重建


2️⃣ 同一层级比较(O(n))

React 不会跨层 diff

复制代码
只比较兄弟节点

3️⃣ key 决定节点复用

ini 复制代码
{list.map(item => (
  <Item key={item.id} />
))}

Diff 的真实过程(列表为例)

无 key(危险)

css 复制代码
A B C
↓
B C D

👉 全部错位复用,性能差


有 key(正确)

scss 复制代码
A(key1) B(key2) C(key3)
↓
B(key2) C(key3) D(key4)

👉 复用 B、C,只增删 A / D


面试话术

React Diff 是基于同层比较和 key 的启发式算法,把复杂度从 O(n³) 降到 O(n)。


七、Fiber 和 Diff 的关系(面试官最爱问)

错误理解 ❌

Fiber = 新 Diff

正确理解 ✅

Diff 算法没变,Fiber 改变的是 Diff 的执行方式和调度模型。


八、为什么 Fiber 能"中断",递归不行?

递归的问题

scss 复制代码
diff(node) {
  diff(node.child)
}
  • 调用栈一旦开始,停不了

Fiber 的优势

ini 复制代码
一个 Fiber = 一个工作单元
  • 执行完一个就可以停
  • 下次从 nextFiber 继续

九、面试官常见追问 & 满分回答

Q1:Fiber 是不是双缓存?

✅ 是

php 复制代码
current Fiber Tree
workInProgress Fiber Tree

提交后互换引用。


Q2:useEffect 在哪执行?

👉 Commit 阶段之后


Q3:为什么 Render 阶段不能操作 DOM?

👉 因为可能被中断,多次执行会出问题。

相关推荐
心在飞扬9 分钟前
ReRank重排序提升RAG系统效果
前端·后端
心在飞扬14 分钟前
RAPTOR 递归文档树优化策略
前端·后端
前端Hardy31 分钟前
别再无脑用 `JSON.parse()` 了!这个安全漏洞你可能每天都在触发
前端·javascript·vue.js
前端Hardy33 分钟前
别再让 `console.log` 上线了!它正在悄悄拖垮你的生产系统
前端·javascript·vue.js
青青家的小灰灰37 分钟前
从入门到精通:Vue3 ref vs reactive 最佳实践与底层原理
前端·vue.js·面试
OpenTiny社区1 小时前
我的新同事是个AI:支持skill后,它用TinyVue搭项目还挺溜!
前端·vue.js·ai编程
是你的小橘呀1 小时前
TypeScript在React项目中的实战应用指南
react.js
心在飞扬1 小时前
MultiVector 多向量检索
前端·后端
用户39051332192881 小时前
async 函数返回的 Promise 状态何时变为 resolved
前端
李剑一1 小时前
大屏天气展示太普通?视觉升级!用 Canvas 做动态天气遮罩,雷阵雨效果直接封神
前端·vue.js·canvas