Fiber 架构作用、时间切片、任务调度

React Fiber 是 React 16 之后引入的新架构,它的核心目标是解决 大型应用渲染卡顿、无法中断渲染、用户交互不流畅 的问题。

Fiber 架构主要涉及三个核心概念:

  1. Fiber 架构

  2. 时间切片(Time Slicing)

  3. 任务调度(Scheduler)


一、为什么需要 Fiber

在 React 15 之前,React 使用的是:

Stack Reconciler(递归架构)

例如:

复制代码
<App>
  <Header />
  <Content>
    <List />
  </Content>
</App>

React 更新时:

复制代码
render()
 ↓
diff
 ↓
更新DOM

整个过程必须一次执行完成。

如果组件树很大:

复制代码
10000个组件

可能需要:

复制代码
16ms
30ms
50ms
甚至100ms

浏览器会被阻塞:

复制代码
React执行中
↓
用户点击
↓
无法响应

出现:

  • 页面卡顿

  • 动画掉帧

  • 输入延迟


二、Fiber 架构是什么

Fiber 本质上是:

复制代码
一种新的协调(Reconciliation)算法
+
一种可中断的链表树结构

React把组件变成一个个 Fiber 节点。

例如:

复制代码
<App>
  <Header />
  <Main />
</App>

Fiber树:

复制代码
App Fiber
│
├── Header Fiber
│
└── Main Fiber

每个 Fiber 节点都是一个 JS 对象:

复制代码
{
  type: App,
  stateNode: DOM,
  child: Fiber,
  sibling: Fiber,
  return: Fiber
}

三、Fiber 节点结构

简化版:

复制代码
const fiber = {
  type,
  stateNode,

  child,
  sibling,
  return,

  pendingProps,
  memoizedProps,

  memoizedState,

  flags
}

重要属性:

child

第一个子节点

复制代码
A
│
├─B
├─C
└─D

A.child = B

sibling

兄弟节点

复制代码
B.sibling = C
C.sibling = D

形成链表:

复制代码
B → C → D

return

父节点

复制代码
B.return = A
C.return = A
D.return = A

整个结构:

复制代码
      A
     /
    B → C → D

变成:

复制代码
child
sibling
return

三指针树。


四、Fiber 工作原理

React 不再递归。

以前:

复制代码
A
 ├─B
 │ ├─D
 │ └─E
 └─C

递归:

复制代码
walk(A)
walk(B)
walk(D)
walk(E)
walk(C)

无法暂停。


Fiber 改成:

复制代码
while(nextFiber){
   performUnitOfWork(nextFiber)
}

每次只处理一个 Fiber。

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

处理完一个节点:

复制代码
暂停
恢复
继续

都可以。


五、时间切片(Time Slicing)

这是 Fiber 最重要的能力。


没有时间切片

假设:

复制代码
React任务
耗时 100ms

浏览器:

复制代码
0ms----------------100ms

React一直执行

用户:

复制代码
点击按钮

必须等待:

复制代码
100ms后响应

很卡。


有时间切片

React:

复制代码
100ms任务

拆成:

复制代码
5ms
5ms
5ms
5ms
...

执行过程:

复制代码
React 5ms
↓
让出主线程
↓
浏览器渲染
↓
React继续5ms
↓
浏览器渲染

这样:

复制代码
用户点击
动画
滚动

都能及时响应。


示意图:

复制代码
无时间切片

|--------------React--------------|

用户无法操作


有时间切片

|React|
      |Render|
             |React|
                    |Render|
                           |React|

六、requestIdleCallback

最初 React 想用:

复制代码
requestIdleCallback()

浏览器空闲时执行任务。

复制代码
requestIdleCallback(deadline => {
   while(deadline.timeRemaining()>0){
      work()
   }
})

问题:

复制代码
兼容性差
不稳定

因此 React 自己实现 Scheduler。


七、任务调度 Scheduler

React 内部有独立调度器:

复制代码
scheduler

作用:

复制代码
决定谁先执行
谁后执行
能否中断

工作流程:

复制代码
更新
 ↓
Scheduler
 ↓
Fiber
 ↓
DOM

八、任务优先级

React 18 有多个优先级。

高优先级:

复制代码
用户输入
点击
键盘事件

低优先级:

复制代码
列表刷新
数据加载

例如:

复制代码
<input />
<ul>
  10000条数据
</ul>

用户输入:

复制代码
高优先级

列表刷新:

复制代码
低优先级

Scheduler:

复制代码
先处理输入
后处理列表

避免输入卡顿。


九、Fiber 双缓存机制

React 有两棵树:

复制代码
Current Fiber Tree
WorkInProgress Fiber Tree

当前页面:

复制代码
Current

更新时:

复制代码
复制一份

Current
      ↓
WorkInProgress

在新树上计算:

复制代码
Diff
State
Props

完成后:

复制代码
直接替换

Current ← WorkInProgress

称为:

复制代码
Double Buffering
双缓存

类似游戏开发中的双缓冲。


十、React 更新流程

React 18 更新过程:

复制代码
setState
    ↓
创建Update
    ↓
加入更新队列
    ↓
Scheduler调度
    ↓
Fiber Reconciliation
    ↓
生成WorkInProgress树
    ↓
Diff
    ↓
Commit阶段
    ↓
更新DOM

分成两个阶段:


Render 阶段

计算阶段

复制代码
可中断
可暂停
可恢复

执行:

复制代码
Fiber Diff
生成新树

Commit 阶段

提交阶段

复制代码
不可中断
同步执行

执行:

复制代码
DOM更新
useLayoutEffect
Ref更新

流程:

复制代码
Render
   ↓
可暂停

Commit
   ↓
不可暂停

十一、React 18 Concurrent 并发模式

Fiber 是基础。

在 Fiber 之上实现:

复制代码
Concurrent Rendering

例如:

复制代码
startTransition(() => {
   setList(bigData)
})

表示:

复制代码
这是低优先级任务

用户输入:

复制代码
setInput()

高优先级。

React:

复制代码
输入优先
列表稍后

实现流畅体验。


面试总结(必须会背)

Fiber 解决什么问题?

解决 React 旧架构无法中断渲染导致页面卡顿的问题。


Fiber 是什么?

Fiber 是 React16 引入的新协调架构,本质是将组件树转换为 Fiber 对象树,并将渲染任务拆分成多个小任务执行。


时间切片是什么?

将长任务拆分成多个短任务执行,每执行一段时间就把主线程让给浏览器,从而保证页面流畅。


Scheduler 是什么?

Scheduler 是 React 的任务调度器,负责任务优先级管理、任务中断与恢复。


Render 和 Commit 区别?

阶段 是否可中断 作用
Render ✅ 可中断 Fiber Diff、生成新树
Commit ❌ 不可中断 更新 DOM、执行 Effect

Fiber 核心链表结构

复制代码
child
sibling
return

形成:

复制代码
父子链表树

这是 React Fiber 面试中最常考的部分,也是理解 React 18 并发渲染(Concurrent Rendering)、startTransitionuseDeferredValue 等高级特性的基础。