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?

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

相关推荐
LZQ <=小氣鬼=>18 分钟前
React 图片放大镜组件使用文档
javascript·react.js·前端框架·ecmascript
kyriewen1139 分钟前
异步编程:从“回调地狱”到“async/await”的救赎之路
开发语言·前端·javascript·chrome·typescript·ecmascript·html5
早點睡39040 分钟前
ReactNative项目Openharmony三方库集成实战:@react-native-clipboard/clipboard
javascript·react native·react.js
Old Uncle Tom40 分钟前
Markdown Viewer 再升级
前端
Luna-player43 分钟前
Vue3中使用vue-awesome-swiper
前端·vue.js·arcgis
SuperEugene1 小时前
Vue3 Pinia 状态管理规范:状态拆分、Actions 写法、持久化实战,避坑状态污染|状态管理与路由规范篇
前端·javascript·vue.js·前端框架·pinia
black方块cxy1 小时前
实现一个输入框多个ip以逗号分隔最多20组,且ip不能重复
java·服务器·前端
@PHARAOH1 小时前
WHAT - AI 时代下的候选人
大数据·前端·人工智能
竹林8182 小时前
从零到一:我在Solana NFT铸造前端中搞定@solana/web3.js连接与交易
前端·javascript
猪八宅百炼成仙2 小时前
不用点击也能预览图片:Element UI ImageViewer 命令式调用方案
前端