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?

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

相关推荐
mCell4 小时前
如何零成本搭建个人站点
前端·程序员·github
mCell5 小时前
为什么 Memo Code 先做 CLI:以及终端输入框到底有多难搞
前端·设计模式·agent
恋猫de小郭5 小时前
AI 在提高你工作效率的同时,也一直在增加你的疲惫和焦虑
前端·人工智能·ai编程
少云清5 小时前
【安全测试】2_客户端脚本安全测试 _XSS和CSRF
前端·xss·csrf
银烛木5 小时前
黑马程序员前端h5+css3
前端·css·css3
m0_607076605 小时前
CSS3 转换,快手前端面试经验,隔壁都馋哭了
前端·面试·css3
听海边涛声5 小时前
CSS3 图片模糊处理
前端·css·css3
IT、木易5 小时前
css3 backdrop-filter 在移动端 Safari 上导致渲染性能急剧下降的优化方案有哪些?
前端·css3·safari
0思必得06 小时前
[Web自动化] Selenium无头模式
前端·爬虫·selenium·自动化·web自动化
anOnion6 小时前
构建无障碍组件之Dialog Pattern
前端·html·交互设计