3分钟搞懂React Fiber,面试涨薪3K不是梦!

81 阅读4分钟

面试官:“聊聊 React Fiber 吧。”
你:“呃……就是 Fiber……一种数据结构?”
面试官微笑,你原地社死。
别慌,看完这篇,你就能把 Fiber 讲成故事,还能顺手画出它的架构图。


一、为什么 15 代的 React 会“卡”?

在 React 15 及更早版本, reconciliation(协调)过程是同步、不可中断的。
浏览器主线程被 React 一把梭哈:

  1. 计算新 Virtual DOM
  2. 和旧树 diff
  3. 一口气把差异 patch 到真实 DOM

页面元素少时还好;一旦组件层级深、节点多,主线程就被长时间霸占,用户输入、动画、滚动全部“卡死”。
痛点总结:同步渲染 = 一旦开始,停不下来。


二、Fiber 的解题思路:把“一口气”拆成“一小口”

React 16 引入的 Fiber 架构,核心只有三句话:

  1. 把渲染任务拆成“工作单元”(unit of work)
  2. 允许工作单元被中断、恢复、甚至丢弃
  3. 让浏览器拿回主线程,优先处理高优任务(如用户输入)

用“装修房子”类比 :

  • 旧 React:一口气装完客厅+卧室+厨房,期间业主敲门都听不见。
  • Fiber:把每间房拆成独立任务卡,随时可停工去开门,回来再继续。

三、Fiber 节点长啥样?——一张“任务卡”的解剖

每个 JSX 元素都会被编译成一个普通的 JavaScript 对象,即 fiber 节点。
核心字段(简化版):

fiber = {
  type,              // 'div' | MyComponent | Fragment …
  key,               // 同级 diff 的“身份证”
  stateNode,         // 对应的 DOM 节点或组件实例
  return,            // 指向“父亲”
  child,             // 指向“长子”
  sibling,           // 指向“下一个兄弟”
  pendingProps,      // 新来的 props
  memoizedProps,     // 上一次渲染用的 props
  memoizedState,     // 上一次渲染用的 state(Hooks 链表就挂在这)
  alternate,         // 指向“另一棵树”上的自己,实现双缓冲
  flags,             // 副作用标记(增 / 删 / 改)
  nextEffect,        // 副作用链表指针
  lanes,             // 优先级车道
}

看见没?fiber 节点 = 虚拟 DOM 节点 + 调度信息 + 副作用信息 + 双缓冲指针
它既是“数据”,也是“待办事项”。


四、双缓冲:画好“新图纸”再一次性贴到墙上

Fiber 维护两棵树:

  • current:屏幕正在显示的旧树
  • workInProgress(WIP):内存中正在构造的新树
  1. 所有更新先在 WIP 树上“草稿”
  2. 等整棵树计算完毕,进入commit 阶段,一次性把差异 patch 到真实 DOM
  3. 树切换:root.current = WIP,旧树变“备胎”

好处:用户永远看不到“半成品”界面,也省去中间状态的回滚成本 。


五、Render vs Commit:能暂停的和不能暂停的

阶段是否可中断做的事类比装修
Render✅ 可中断构建 WIP 树,diff,打副作用标记画新图纸,可停笔
Commit❌ 不可中断操作真实 DOM,触发生命周期 / useEffect贴瓷砖,必须一口气

六、优先级车道(Lanes)——“业主说先装厨房”怎么办?

React 把更新按紧急程度拆成 32 条车道

  • 输入 / 点击 → 高优(同步车道)
  • 列表渲染 / 数据同步 → 低优(空闲车道)

高优任务可以插队低优任务;被插队的低优任务回到 WIP 池,等下次空闲继续。
这就是 useTransitionstartTransition 的底层依赖 。


七、工作循环:浏览器给 React“发饷”——一帧一帧领工资

function workLoop(deadline) {
  while (nextUnitOfWork && deadline.timeRemaining() > 0) {
    nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
  }
  if (!nextUnitOfWork) {
    // WIP 树构建完成,进入 commit
    commitRoot();
  } else {
    // 没干完,下帧继续
    requestIdleCallback(workLoop);
  }
}
  • performUnitOfWork:处理一个 fiber 节点,返回“下一个节点”
  • requestIdleCallback:浏览器空闲时再把主线程“租”给 React

协作式调度:React 不抢,浏览器给多少时间干多少活,用户永远优先。


八、从 Fiber 到并发特性:Suspense、useTransition 诞生记

Fiber 只是“基建”,上层长出了:

  • 时间切片(Time-slicing):把长列表拆成多帧渲染
  • Suspense:组件“等数据”时先不进入 commit,避免白屏
  • useTransition:把 setState 标记为可中断,低优更新不堵高优输入

这些特性共同构成 React 18 的 Concurrent Rendering


九、面试“秒答”模板:背下来,再讲出故事

Q:什么是 React Fiber?
A:
Fiber 是 React 16 起全新的协调引擎,它把原本同步不可中断的渲染过程拆成可暂停 / 恢复 / 优先级排序的小任务。
每个 React 元素对应一个fiber 节点,节点以链表形式串联成树,并通过双缓冲机制在内存中构建新树,再一次性提交。
这使得 React 能在不阻塞主线程的前提下完成大型更新,也为 Suspense、useTransition 等并发特性打下基础。


十、30 秒手绘知识脑图(文字版)

Fiber 节点
 ├─ 数据层:type/key/props/state
 ├─ 链接层:return/child/sibling
 ├─ 副作用:flags + nextEffect 链表
 ├─ 双缓冲:alternate 指针
 └─ 优先级:lanes 车道

Render 阶段(可中断)
 ↓
commit 阶段(同步执行)
 ↓
Concurrent 特性

十一、总结:记住三句话,Fiber 永不慌

  1. Fiber = 工作单元 + 链表树 + 双缓冲
  2. Render 可中断,Commit 必同步
  3. 没有 Fiber,就没有并发特性,也没有不卡的主线程

下次再被问到“React Fiber 是什么?”
别背定义,讲故事。
从“装修房子”讲起,再甩三个核心点,面试官会眼前一亮。


如果本文对你有帮助,点个 分享 给正在准备面试的小伙伴吧!