万字长文介绍React Fiber架构的原理和工作模式

万字长文介绍React Fiber架构的原理和工作模式
最新回答
偶尔动情

2023-10-02 20:47:13

我花费了5天时间深入研究Fiber的核心源码,尽管本文篇幅超过万字,但对于数十万行的Fiber源码来说,仅能算是对其基础知识的一个简要介绍。若文中存在疏漏,欢迎在评论区指出,我将及时更新。若您对Fiber有特定的专题想了解,也欢迎在评论区提出,我很乐意继续深入研究源码并分享知识。

自React 16版本开始,React引入了Fiber架构,旨在解决之前更新机制存在的问题。在长时间更新过程中,主线程可能会被阻塞,导致应用无法及时响应用户输入。本文将探讨Fiber的底层原理及其工作模式,让您对Fiber架构有一个清晰的认识。

本文首发于我的博客「J实验室」。

欢迎加入「独立全栈开发交流群」,共同学习交流前端和Node端技术。

首先,我们来了解一下React的基本组成:当编写React组件并使用JSX时,React在底层会将JSX转换为元素的对象结构。例如:

上述代码会被转换为以下形式:

为了将这个元素渲染到DOM上,React需要创建一种内部实例,用来追踪该组件的所有信息和状态。在早期版本的React中,我们称之为“实例”或“虚拟DOM对象”。但在Fiber架构中,这个新的工作单元就叫做Fiber。

在本质上,Fiber是一个JavaScript对象,代表React的一个工作单元,它包含了与组件相关的信息。一个简化的Fiber对象长这样:

当React开始工作时,它会沿着Fiber树形结构进行,试图完成每个Fiber的工作(例如,比较新旧props,确定是否需要更新组件等)。如果主线程有更重要的工作(例如,响应用户输入),则React可以中断当前工作并返回执行主线程上的任务。

因此,Fiber不仅仅是代表组件的一个内部对象,它还是React的调度和更新机制的核心组成部分。

在React 16之前的版本中,使用递归的方式处理组件树更新,称为堆栈调和(Stack Reconciliation)。这种方法一旦开始就不能中断,直到整个组件树都被遍历完。这种机制在处理大量数据或复杂视图时可能导致主线程被阻塞,从而使应用无法及时响应用户的输入或其他高优先级任务。

Fiber的引入改变了这一情况。Fiber可以理解为是React自定义的一个带有链接关系的DOM树,每个Fiber都代表了一个工作单元,React可以在处理任何Fiber之前判断是否有足够的时间完成该工作,并在必要时中断和恢复工作。

现在,我们来了解一下FiberNode的结构:

其实可以理解为是一个更强大的虚拟DOM。

Fiber工作原理中最核心的点就是:可以中断和恢复,这个特性增强了React的并发性和响应性。

实现可中断和恢复的原因就在于:Fiber的数据结构里提供的信息让React可以追踪工作进度、管理调度和同步更新到DOM。

了解了Fiber的工作原理后,我们可以通过阅读源码来加深对Fiber的理解。React Fiber的工作流程主要分为两个阶段:

第一阶段:Reconciliation(调和)

调和阶段又分为三个小阶段:

1、创建与标记更新节点:beginWork

2、收集副作用列表:completeUnitOfWork和completeWork

调和阶段知识拓展

1、为什么Fiber架构更快?

2、调和过程可中断

第二阶段:Commit(提交)

源码里commitRoot和commitRootImpl是提交阶段的入口方法,在两个方法中,可以看出来提交阶段也有三个核心小阶段,我们一一讲解:

1、遍历副作用列表:BeforeMutation

2、正式提交:CommitMutation

3、处理layout effects:commitLayout

从源码里我们可以看到,一旦进入提交阶段后,React是无法中断的。

以上内容虽无法覆盖Fiber的方方面面,但可以确保你学完后对Fiber会有一个整体上的认识,并且让你在以后阅读互联网上其它关于Fiber架构的文章时,不再因为基础知识困惑,而是能够根据已有的思路轻松地拓展你大脑里关于Fiber架构的知识网。

欢迎加入「独立全栈开发交流群」,共同学习交流前端和Node端技术。