为什么说 React 更新是可中断的?从 Fiber 到任务调度全揭秘!

53 阅读1分钟

React 的一次完整更新过程,可拆解为以下 5 个阶段:

  1. 触发更新

state或者props变化,触发更新流程

引起更新的setState会被包装成有过期时间和优先级的Update对象,推进Fiber.UpdateQueue

  1. Schedule

根据Update对象的过期时间和优先级,

  • 如果是同步/高优先级任务,推进taskQueue立即任务队列,等待执行
  • 如果是优先级不高的任务,推进timerQueue延迟任务队列
  1. Recondiler

  • 调和算法开始 diff 对比:

    • 比较新旧 Fiber 树,标记变化(effectTag)
    • 判断是:插入、更新、删除
  • 递归生成新的 workInProgress Fiber 树

  1. Render

  • DFS 递归遍历workInProgress Fiber 树:

    • beginWork:对当前 fiber 进行更新、比较老 props 和新 props
    • completeWork:收集副作用,构建 effect 链表(effectList)
    • 不涉及实际 DOM 操作,可中断、恢复(支持时间切片)
  1. Commit

  • 不可中断! 会真正执行副作用和 DOM 操作。分 3 步:
阶段作用
beforeMutation执行生命周期 getSnapshotBeforeUpdate
mutationDOM 更新:插入、更新、删除
layout执行 useLayoutEffect

问题快速回答
React 为什么引入 Fiber?为了实现任务拆分、时间切片、中断恢复、提高渲染流畅度
Render 和 Commit 有什么区别?Render 阶段 diff,纯计算;Commit 执行 DOM 更新、生命周期
updateQueue 和 taskQueue 区别?updateQueue 是 Fiber 层的更新链表,taskQueue 是全局调度任务队列
React 哪些阶段是可中断的?Render 阶段可中断;Commit 阶段不可中断