FiberNode详解
# 概览
Fiber是React Fiber架构中的最小工作单元,每个React元素对应一个Fiber节点。
# 源码
# createFiberImplClass方法
React中Fiber节点初始化是调用的createFiberImplClass,该方法就是创建一个Fiber节点,并返回Fiber节点实例。
function createFiberImplClass(tag, pendingProps, key, mode) {
return new FiberNode(tag, pendingProps, key, mode);
}
1
2
3
2
3
# FiberNode
FiberNode就是个函数,拥有很多属性。其实现如下:
function FiberNode(tag, pendingProps, key, mode) {
this.tag = tag;// 节点类型,如函数组件、类组件、原生DOM元素等
this.key = key;// 即React元素上的key,可用于在列表中进行diff时标识元素
/** 连接属性 */
this.sibling = // 指向下一个兄弟Fiber节点,形成一个单链表
this.child = // 指向第一个子Fiber节点
this.return = // 指向父Fiber节点
this.stateNode = // 对于DOM节点,表示DOM节点实例;对于类组件,表示组件实例;对于函数组件,则为null
this.type = // 对于函数组件和类组件,则为它们自身;对于DOM元素,则表示标签名字符串
this.elementType = // 大部分情况和type相同,在使用React.memo或React.forwardRef时,表示包裹前的组件类型
null;
this.index = 0; // 当前节点在兄弟节点中的索引,用于调和算法
this.refCleanup = //用于清理ref的函数,在卸载时执行
this.ref = null; //执行React元素上的ref属性,可以是一个回调函数或ref对象
this.pendingProps = pendingProps; // 表示新的、还未处理的props,即本次渲染中该节点应该要使用的props
this.dependencies =//与当前Fiber节点相关的上下文、事件订阅等依赖项
this.memoizedState = // 对于类组件,存放state;对于函数组件,保存了hook链表;对于其他类型节点,为null
this.updateQueue = //用于状态更新、回调函数、DOM更新的队列
this.memoizedProps = // 表示上一次渲染时使用的props
null;
this.mode = mode; // 表示当前Fiber所在树的模式,比如同步模式、并发模式等
this.subtreeFlags = this.flags = 0; // 用于记录当前Fiber节点及其子树的副作用
this.deletions = null;//记录当前节点需要删除的子节点列表(在协调阶段标记为删除的节点)
this.childLanes = // 子节点的更新优先级
this.lanes = 0; // 当前节点的更新优先级
this.alternate = null; //指向当前Fiber节点在另一颗树(workInProgress树或current树)中对应的Fiber节点
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 节点类型
export const FunctionComponent = 0; // 函数组件
export const ClassComponent = 1; // 类组件
export const HostRoot = 3; // 宿主根节点,React应用入口,ReactDOM.createRoot
export const HostPortal = 4; // Portal组件,ReactDOM.createPortal
export const HostComponent = 5; // 原生DOM元素组件,<div> <span>等
export const HostText = 6; // 文本节点
export const Fragment = 7; // Fragment组件 React.Fragment或<>...</>
export const Mode = 8; //严格模式组件 React.StrictMode
export const ContextConsumer = 9;//Context消费者
export const ContextProvider = 10; // Context提供者
export const ForwardRef = 11; // Forward Ref组件, React.forwardRef
export const Profiler = 12; // 性能分析组件,React.Profiler
export const SuspenseComponent = 13; // Suspense组件,数据加载边界
export const MemoComponent = 14; // Memo组件 React.memo
export const SimpleMemoComponent = 15; // 浅比较memo组件
export const LazyComponent = 16; // 懒加载组件 React.lazy(()=>import('.../component'))
export const IncompleteClassComponent = 17; //未完成的类组件,渲染过程中抛出错误
export const DehydratedFragment = 18; // 脱水片段 SSR客户端激活
export const SuspenseListComponent = 19; // Suspense 列表-协调多个suspense
export const ScopeComponent = 21; // 作用域组件
export const OffscreenComponent = 22; // 离屏组件
export const LegacyHiddenComponent = 23; //传统隐藏组件,已被OffscreenComponent替代
export const CacheComponent = 24; // 缓存组件
export const TracingMarkerComponent = 25; // 性能追踪组件
export const HostHoistable = 26; // 资源预加载-可提升的宿主组件
export const HostSingleton = 27;//宿主单例
export const IncompleteFunctionComponent = 28; // 未完成的函数组件
export const Throw = 29;// 抛出组件-错误处理占位
export const ViewTransitionComponent = 30; // 视图过渡组件-页面过渡动画
export const ActivityComponent = 31; // 活动组件-保持活动状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Fiber节点的tag类是React内部对不同组件进行分类的重要机制:
- 性能优化:不同类型组件有不同优化策略
- 错误处理:特殊 tag 用于错误边界和恢复
- 并发特性:新 tag 支持并发渲染特性
- 向后兼容:保留旧 tag 支持旧版本
- 渐进增强:新功能通过新 tag 逐步引入
# Fiber节点的应用场景
- 任务调度与可中断渲染
// React 的工作循环
function workLoopConcurrent() {
while (workInProgress !== null && !shouldYield()) {
performUnitOfWork(workInProgress);
}
// 可以中断,让出主线程控制权
}
1
2
3
4
5
6
7
2
3
4
5
6
7
- 优先级调度
// 不同优先级的处理
const lanes = [
SyncLane, // 同步优先级
InputContinuousLane, // 连续输入
DefaultLane, // 默认
IdleLane // 空闲
];
// 根据优先级安排工作
scheduleUpdateOnFiber(root, fiber, lane);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 增量更新
// 将渲染工作分成小任务
function performUnitOfWork(unitOfWork) {
const next = beginWork(unitOfWork);
if (next === null) {
completeUnitOfWork(unitOfWork);
} else {
workInProgress = next;
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 总结
Fiber 架构通过将渲染工作拆分成多个可中断的单元(Fiber 节点),实现了:
- 可中断渲染:优先级高的任务可以中断低优先级任务
- 增量渲染:将工作分解为多个帧执行
- 时间切片:在每一帧中分配固定的时间给 React,5ms
- 双缓存:平滑切换 UI,避免闪烁
- 并发更新:多个状态更新可以同时进行
每个 Fiber 节点都是一个工作单元,包含了组件的所有必要信息,React 通过这些节点构建了一棵虚拟的组件树,并通过遍历这棵树来完成渲染工作。
编辑 (opens new window)
上次更新: 2026/01/20, 09:26:42