以下是关于 Fiber 架构 的系统梳理:
一、Fiber 架构的出现背景
-
React 15 及之前的问题
- 同步递归渲染:虚拟DOM的diff过程不可中断,导致主线程长时间阻塞。
- 掉帧问题:复杂组件树渲染时,用户交互无法及时响应。
- 无法实现增量渲染:无法拆分任务优先级,无法利用浏览器空闲时间。
-
核心设计目标
- 可中断的异步渲染:将渲染任务拆分为小任务单元。
- 优先级调度:高优先级任务(如用户输入)优先处理。
- 增量更新:利用浏览器空闲时间执行任务。
二、Fiber 的核心概念
-
Fiber 是什么
- 数据结构:每个React元素对应一个Fiber节点,保存组件状态、DOM引用等信息。
- 调度单位:最小的可中断任务单元。
- 工作单元:描述“当前需要完成的工作”(如更新组件、挂载DOM)。
-
Fiber 节点结构(简化版)
interface Fiber {type: Function | string; // 组件类型(函数/类组件、DOM标签)key: string | null; // 唯一标识stateNode: any; // 对应实例(DOM节点/组件实例)child: Fiber | null; // 第一个子节点sibling: Fiber | null; // 下一个兄弟节点return: Fiber | null; // 父节点alternate: Fiber | null; // 指向另一棵树的对应节点(双缓存)effectTag: number; // 标记需要执行的副作用(如插入、更新、删除)memoizedState: any; // 存储状态(如hooks链表)pendingProps: any; // 新传入的propsmemoizedProps: any; // 当前生效的props// ...其他字段(如优先级标记) }
-
Fiber 树 vs 虚拟DOM树
- 虚拟DOM树:静态的树结构,用于diff算法。
- Fiber 树:动态的链表结构,包含调度和状态信息。
三、Fiber 架构的工作原理
-
双缓存机制(Double Buffering)
- Current 树:当前屏幕上显示的树。
- WorkInProgress 树:正在构建的新树。
- 交替更新:更新完成后,WorkInProgress 树成为新的 Current 树。
-
渲染阶段拆分
- 协调阶段(Reconciliation Phase)
- 可中断:遍历Fiber树,标记需要更新的节点(生成effect list)。
- 执行操作:调用生命周期方法、执行Hooks、计算diff。
- 提交阶段(Commit Phase)
- 不可中断:将effect list应用到真实DOM。
- 执行操作:DOM更新、调用
componentDidUpdate
等。
- 协调阶段(Reconciliation Phase)
-
调度流程