React Fiber
什么是Fiber?
Fiber是React 16.8.0-alpha.1版本中引入的新概念。本质上其实就是一种数据结构,可以用一个纯js对象表示:
const fiber = {
stateNode, // 节点实例
child, // 子节点
sibling, // 兄弟节点
return, // 父节点
}
Fiber是一个执行单元,每次执行完一个执行单元,React会检查现在还剩余多少时间,如果没有时间就会将控制权进行转让。
为什么引入Fiber?
在未引入Fiber之前,React的渲染是通过递归调用render函数进行的,由于JS本身是单线程的并且和UI线程是互斥的,当我们一次性渲染大量的Dom节点时就会非常的耗时,给用户一种卡顿的感觉,为了解决这个问题,React引入了Fiber。
-
增量渲染:React Fiber 的核心目标之一就是实现增量渲染。传统的渲染方式是同步的,一旦开始渲染,就会一直执行直到完成,这样可能导致页面在渲染过程中出现卡顿,用户体验不佳。React Fiber 通过引入协调和分时处理的概念,使得渲染工作可以被中断和恢复,从而实现更加平滑的用户界面更新。这种增量渲染的方式可以在每一帧中分配一小部分工作,而不是一次性完成整个渲染过程。
-
不同更新的优先级:React Fiber 的核心目标之一就是实现增量渲染。传统的渲染方式是同步的,一旦开始渲染,就会一直执行直到完成,这样可能导致页面在渲染过程中出现卡顿,用户体验不佳。React Fiber 通过引入协调和分时处理的概念,使得渲染工作可以被中断和恢复,从而实现更加平滑的用户界面更新。这种增量渲染的方式可以在每一帧中分配一小部分工作,而不是一次性完成整个渲染过程。
-
暂停、终止、复用渲染任务:React Fiber 的核心目标之一就是实现增量渲染。传统的渲染方式是同步的,一旦开始渲染,就会一直执行直到完成,这样可能导致页面在渲染过程中出现卡顿,用户体验不佳。React Fiber 通过引入协调和分时处理的概念,使得渲染工作可以被中断和恢复,从而实现更加平滑的用户界面更新。这种增量渲染的方式可以在每一帧中分配一小部分工作,而不是一次性完成整个渲染过程。
-
并发方便新的基础能力: React Fiber 的架构使得并发成为可能。在 React Fiber 中,任务可以以并发的方式进行,不同任务之间可以交叉执行,而不会阻塞整个渲染过程。这为引入一些新的基础能力提供了可能性,例如 Suspense 和 concurrent rendering。Suspense 允许组件在等待异步数据加载完成时暂停渲染,而 concurrent rendering 允许 React 在多个优先级的任务之间动态地切换和调整,以更好地适应不同的环境和设备。
Fiber的执行流程
-
ReactDom.render()引导React启动或者调用setState() 的时候开始创建或更新FiberTree。
-
从根节点开始便遍历Fiber Node Tree并且构建WokeInProgress Tree(待更新的树)。
- 本阶段可以进行暂停、终止、和重启,会导致React生命周期的重复进行。
- React会在该阶段生成两棵树,一个是用来表示当前状态的current Tree,另一个则是待更新的workInProgress Tree。
- 遍历current Tree,重用或者更新Fiber Node带workInProgress Tree。当workInProgress Tree构建完成后会替代current Tree。
- 每更新一个节点同时生成对用的Effect List。
- 为每个节点创建更新任务。
-
将创建的更新任务介入到任务队列中等待调度。
- 调度有scheduler模块负责,scheduler模块会根据任务的优先级进行调度。
- scheduler模块实现了跨平台兼容的requestIdleCallback。
- 每处理完一个FiberNode更新后,可以终端、挂起或者恢复。
-
根据Effect List完成Dom更新。
- React会对Effect List进行遍历,将所有的变更一次更新到Dom上。
- 这一阶段会导致页面重新渲染所以是不可中断的。
流程图: