# React-Fiber

# Fiber 是什么

JavaScript 是单线程的,这意味着我们只有一个线程可以执行所有UI更新,处理用户操作和网络调用等。

在 Fiber 之前 React 有两棵树🌲,一棵是当前树,另一棵是带有所有新更新的更新树🌲。 协调器将在一次通过中同步找到两个树🌲之间的差异,这个过程不能被打断,得全部执行完一把梭更新, 节点过多会导致卡顿,这将阻止主线程执行其他重要任务,例如某些用户操作

因此,Facebook团队在React 16更新中引入了Fiber作为其核心架构。

Fiber 就是一个数据结构,它有很多属性,虚拟 dom 就是对真实 dom 的一种简化 一些真实 dom 做不到的对象 虚拟 dom 更做不到。 因此有了 fiber、希望借由 fiber 上的这堆属性 来做一些比较厉害的事件

# Fiber 架构

为了弥补上面的不足、设计了一些新的算法、为了让这些算法跑起来、所以出现了 Fiber 数据结构

Fiber 数据结构 + 算法 = Fiber 架构

React 应用从始至终 管理着最基本的三样东西

  1. Root(整个应用的根 一个对象 不是 Fiber 同时有个属性指向 workInProgress)

  2. current 树(树上的每一个节点都是 Fiber 保存的是上一次的状态 并且每个FIber节点 都对应这一个 jsx 节点)

  3. workInProgress 树(树上的每一个节点Fiber 保存的是本次新的节点 并且每个Fiber 节点都对应一个 jsx 节点)

# 如何工作

没有 current 树,React 在一开始创建 Root 就会创建一个 uninitiaFiber (未初始化的FIber) 让 react 的 current 指向 uninitiaFiber,之后再去创建一个本次要用到的 workInProgress

  • ReactDOM.render() 和 setState 的时候开始创建更新。
  • 将创建的更新加入任务队列,等待调度。
  • 在 requestIdleCallback 空闲时执行任务。
  • 从根节点开始遍历 Fiber Node,并且构建 WokeInProgress Tree。
  • 生成 effectList。
  • 根据 EffectList 更新 DOM。

WorkInProgress Tree 构造完毕,得到的就是新的 Fiber Tree,然后喜新厌旧(把 current 指针指向 WorkInProgress Tree,丢掉旧的 Fiber Tree)就好了。

这样做的好处:

  • 能够复用内部对象(fiber)

  • 节省内存分配、GC的时间开销

就算运行中有错误,也不会影响 View 上的数据

每个 Fiber上都有个 alternate属性,也指向一个 Fiber,创建 WorkInProgress 节点时优先取 alternate,没有的话就创建一个。

创建 WorkInProgress Tree 的过程也是一个 Diff 的过程,Diff 完成之后会生成一个 Effect List,这个 Effect List 就是最终 Commit 阶段用来处理副作用的阶段。

# React 主要分两个阶段

react-fiber

  1. render 阶段 指的是创建 fiber 过程
  • 为每个节点创建新的 fiber(workInProgress) 可能是复用 生成一棵有新状态的 workInProgress 树
  • 初次渲染的时候(或新创建了某个节点) 会将这个 fiber 创建真实的dom 实例,并且对当前节点的子节点进行插入 appendchild
  • 如果不是初次渲染的话 就对比新旧的 fiber 状态 将产生了更新的fiber节点 最终通过链表的形式挂在到 RootFiber
  1. commit 阶段 才是真正要操作页面的阶段
  • 执行生命周期
  • 会从 RootFiber 上获取到那条链表 根据链表上的标识 来操作页面

在渲染阶段调用的生命周期方法:

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render

不管是初次渲染还是更新 都是从根往下遍历的

在提交阶段调用的生命周期方法:

  • getSnapshotBeforeUpdate
  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

由于这些方法在提交阶段被调用,因此它们可能包含任何副作用和DOM操作操作

这里要特别注意的是,阶段1(渲染)可以暂停和恢复,即,它是异步的,而阶段2必须在一个流程中完成(同步)。

# Prioritization

React系统如何确定要暂停/恢复哪个进程?

优先级 是React Fiber最重要的功能之一。 Fiber Reconciler为任务分配优先级,并根据优先级将更新这些更改

根据任务,React分配以下优先级:

  • 同步
  • 高优先级
  • 低优先级
  • 场外工作(优先)等

例如,在所有组件的优先级中,将textInput类型事件指定为高优先级。

按照优先级执行,如果插入了新的任务,那么也按照优先级重新排序,分别是 window.requestAnimationFramewindow.requestIdleCallback

更新时间: 11/24/2020, 10:17:53 AM