React 的一次完整更新过程,可拆解为以下 5 个阶段:
-
触发更新
state或者props变化,触发更新流程
引起更新的setState会被包装成有过期时间和优先级的Update对象,推进Fiber.UpdateQueue
-
Schedule
根据Update对象的过期时间和优先级,
- 如果是同步/高优先级任务,推进taskQueue立即任务队列,等待执行
- 如果是优先级不高的任务,推进timerQueue延迟任务队列
-
Recondiler
-
调和算法开始 diff 对比:
- 比较新旧 Fiber 树,标记变化(effectTag)
- 判断是:插入、更新、删除
-
递归生成新的 workInProgress Fiber 树
-
Render
-
DFS 递归遍历workInProgress Fiber 树:
beginWork:对当前 fiber 进行更新、比较老 props 和新 propscompleteWork:收集副作用,构建 effect 链表(effectList)- 不涉及实际 DOM 操作,可中断、恢复(支持时间切片)
-
Commit
- 不可中断! 会真正执行副作用和 DOM 操作。分 3 步:
| 阶段 | 作用 |
|---|---|
beforeMutation | 执行生命周期 getSnapshotBeforeUpdate |
mutation | DOM 更新:插入、更新、删除 |
layout | 执行 useLayoutEffect 等 |
| 问题 | 快速回答 |
|---|---|
| React 为什么引入 Fiber? | 为了实现任务拆分、时间切片、中断恢复、提高渲染流畅度 |
| Render 和 Commit 有什么区别? | Render 阶段 diff,纯计算;Commit 执行 DOM 更新、生命周期 |
| updateQueue 和 taskQueue 区别? | updateQueue 是 Fiber 层的更新链表,taskQueue 是全局调度任务队列 |
| React 哪些阶段是可中断的? | Render 阶段可中断;Commit 阶段不可中断 |