在 React 15 时代已经可见一斑:正是出于对“快速响应”的执着,React 才会想方设法把原本 O(n3) 的 Diff 时间复杂度优化到了前无古人的 O(n)
随着时间的推移和业务复杂度的提升,React 曾经被人们津津乐道的 Stack Reconciler 也渐渐在体验方面显出疲态。
为了更进一步贯彻“快速响应”的原则,React 团队“壮士断腕”,在 16.x 版本中将其最为核心的 Diff 算法整个重写,使其以“Fiber Reconciler”的全新面貌示人
Stack Reconciler 到底有着怎样根深蒂固的局限性?
栈调和机制下的 Diff 算法,其实是树的深度优先遍历的过程,当处理结构相对复杂、体量相对庞大的虚拟 DOM 树时,Stack Reconciler 需要的调和时间会很长,这就意味着 JavaScript 线程将长时间地霸占主线程,进而导致我们上文中所描述的渲染卡顿/卡死、交互长时间无响应等问题
栈调和机制下,React 的渲染和更新阶段依赖的是如下图所示的两层架构:
Fiber 架构:是实现“增量渲染”,是为了实现任务的可中断、可恢复,并给不同的任务赋予不同的优先级,最终达成更加顺滑的用户体验(核心“可中断”“可恢复”与“优先级”)
React 16 中,为了实现“可中断”和“优先级”,两层架构变成了如下图所示的三层架构:
多出来的这层架构,叫作“Scheduler(调度器)”,调度器的作用是调度更新的优先级首先,每个更新任务都会被赋予一个优先级。当更新任务抵达调度器时,高优先级的更新任务(记为 A)会更快地被调度进 Reconciler 层;此时若有新的更新任务(记为 B)抵达调度器,调度器会检查它的优先级,若发现 B 的优先级高于当前任务 A,那么当前处于 Reconciler 层的 A 任务就会被中断,调度器会将 B 任务推入 Reconciler 层。当 B 任务完成渲染后,新一轮的调度开始,之前被中断的 A 任务将会被重新推入 Reconciler 层,继续它的渲染之旅,这便是所谓“可恢复”。