React 的 State Recconciler 也渐渐在体验方面显出疲态,在 16.x 版本中将其最核心的 Diff 算法整个重写为 “Fiber Reconciler”

多线程的浏览器除了处理 JS 线程外,还要处理各种任务线程

  • 处理 DOM 的 UI 渲染线程
  • JavaScript 线程是可以操作 DOM
    • 如果渲染线程与 JS 线程同时工作,那么渲染结果必然是难以预测
    • JS 线程和渲染线程必须是互斥,当中一个线程执行时,另一个线程只能挂起等待

单线程的 JS

  • 当事件触发,对应任务不会立刻执行
  • 由事件线程添把事件添加至任务队列末尾
  • 等待同步代码完成后在空闲时间执行出队

渲染层面的更长时间等待,界面长时间不更新,会给用户带来“卡顿”的体验。这就是 State Recconciler 面临的困境
image.png

调和器重复“父组件调用子组件”的过程,直到最深的一层节点更新完毕,才慢慢向上返回。

这个过程是致命性在于同步不可被打断。
State Reconciler 需要的调和时间会很长,这意味 JS 线程将长时间地霸占主线程。进而导致渲染卡顿/卡死、交互长时间无响应等问题。

Fiber 是如何解决问题

什么是 Fiber?

Fiber 就是比线程还要纤细的过程,也就是所谓的“纤程”。纤程的出现意在对渲染过程实现更加精细的控制。

从架构角度来看,Fiber 是对 React 核心算法的重写
从编码角度来看,Fiber 是 React 内部所定义的一种数据结构
从工作流的角度来看,Fiber 节点保存了组件需要更新的状态和副作用

Fiber 架构的应用目的是实现“增量渲染

  • 把一个渲染任务分解为多个渲染任务,然后分散到多个帧中
  • 实现增量渲染的目的是为了实现任务的可中断、可恢复,并给不同的任务赋予不同的优先级,最终达成更加顺滑的用户体验。

    Fiber 架构核心

  • 可中断

  • 可恢复
  • 优先级

image.pngimage.png
改变为
image.pngimage.png
每个更新任务都会被赋予一个优先级

  • 若发现 B 的优先级高于当前任务 A,当前牌 Reconciler 层的 A 任务会被中断
  • A 任务将会被重新推入 Reconciler 层,继续它的渲染,这就是可恢复


Fiber 架构对生命周期的影响

render 的工作单元有着不同的优先级,React 可以根据优先级的高低实现工作单元打断和恢复
render 阶段中的工作用户是零感知,但是会对生命周期的一些方法有影响

  • componentWillMount
  • componentWillUpdate
  • shouldComponentUpdate
  • componentWillReceiveProps