# React Fiber

React Fiber是React16中新的协调引擎。 它可以实现任务分割,让调度算法(reconciliation)能够暂停、恢复

update: 2020-04-11

# Fiber的原因

TIP

React的核心流程分为两部分:

  • reconciliation(调度算法)
    • 更新state/props、调用生命周期钩子、生成virtual dom、通过diff算法、重新渲染
  • commit
    • 操作dom节点更新

原因:大量的组件渲染会导致主进程长时间被占用,导致出现卡顿和掉帧的情况。

旧状:因为在之前的调度算法中,React对组件树是通过同步递归渲染,并且无法暂停和恢复。

# 原理

React Fiber可以实现任务分割。

主要原理是:将任务分割成一个个独立的小任务,将这些小任务分散到浏览器的各个空闲期间(由requestIdleCallback告知)执行。(根据不同的优先级)

特点是:能充分利用主进程的事件循环机制

# 大致数据结构

alt

class Fiber {
    constructor (instance) {
        this.instance = instance;
        // 指向第一个 child 节点
        this.child = child;
        // 指向父节点
        this.return = parent;
        // 指向第一个兄弟节点
        this.sibling = previous;

        // Fiber节点里的Hooks链表
        this.memoizedState = Hooks // <-- 伪代码
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 具体实现机制

# 暂停和恢复

React V16将reconciliation进行了重构(stack reconciler -> fiber reconciler),变成了 简单的链表遍历

通过指针映射,每个单元都记录着上一步、下一步,从而变得可以被暂停和恢复。

# 分散执行

通过两个新API:requestIdleCallbackrequestAnimationFrame

# requestIdleCallback

浏览器提供的事件循环空闲期的回调函数。低优先级的任务交给requestIdleCallback

requestIdleCallbackAPI:

window.requestIdleCallback(
    // 浏览器在空闲时,会执行这个回调,同时会给回调传入一个dealine对象
    // 在dealine对象中包含着浏览器目前有多少时间供我们执行
    callback: (dealine: IdleDeadline) => void,
    // 为了避免浏览器因繁忙且无剩余时间导致的饿死,可传入一个超时时间来强制让浏览器执行回调。
    option?: { timeout: number }
)
1
2
3
4
5
6
7

# requestAnimationFrame

高优先级的任务交给requestAnimationFrame

# 其它

Fiber 比 Stack 的方式要花费更多的内存占用和执行性能,但React 基于 Fiber 的思路会让 JS 执行性能提升。

# Fiber 的衍生产物 Custom Renderer

它定义了一系列标准化的接口,使我们不必关心 Fiber 内部是如何工作的,就可以通过虚拟 DOM 的方式驱动宿主环境。

-->
更新时间: 12/17/2020, 9:23:39 AM