Open zhiqiang21 opened 4 months ago
本篇文章是对React Fiber架构调度器(Scheduler)、协调器(Reconciler)、渲染器(Renderer)的总结。
function FiberNode( tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode, ) { // 作为静态数据结构的属性 this.tag = tag; this.key = key; this.elementType = null; this.type = null; this.stateNode = null; // 用于连接其他Fiber节点形成Fiber树 this.return = null; this.child = null; this.sibling = null; this.index = 0; this.ref = null; // 作为动态的工作单元的属性 this.pendingProps = pendingProps; this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; this.dependencies = null; this.mode = mode; this.effectTag = NoEffect; this.nextEffect = null; this.firstEffect = null; this.lastEffect = null; // 调度优先级相关 this.lanes = NoLanes; this.childLanes = NoLanes; // 指向该fiber在另一次更新时对应的fiber this.alternate = null; }
在React中最多会同时存在两棵Fiber树。当前屏幕上显示内容对应的Fiber树称为current Fiber树,正在内存中构建的Fiber树称为workInProgress Fiber树。
current Fiber树中的Fiber节点被称为current fiber,workInProgress Fiber树中的Fiber节点被称为workInProgress fiber,他们通过alternate属性连接。
JSX是一种描述当前组件内容的数据结构,他不包含组件schedule、reconcile、render所需的相关信息。
JSX
比如如下信息就不包括在JSX中:
优先级
state
标记
这些内容都包含在Fiber节点中。
Fiber节点
所以,在组件mount时,Reconciler根据JSX描述的组件内容生成组件对应的Fiber节点。
mount
Reconciler
在update时,Reconciler将JSX与Fiber节点保存的数据对比,生成组件对应的Fiber节点,并根据对比结果为Fiber节点打上标记。
update
render阶段开始于performSyncWorkOnRoot或performConcurrentWorkOnRoot方法的调用。这取决于本次更新是同步更新还是异步更新。
render阶段
performSyncWorkOnRoot
performConcurrentWorkOnRoot
// performSyncWorkOnRoot会调用该方法 function workLoopSync() { while (workInProgress !== null) { performUnitOfWork(workInProgress); } } // performConcurrentWorkOnRoot会调用该方法 function workLoopConcurrent() { // shouldYield 当前帧是否有空余时间 while (workInProgress !== null && !shouldYield()) { performUnitOfWork(workInProgress); } }
在渲染阶段,使用深度优先遍历每个fiber,为每个遍历到的Fiber节点使用 beginWork方法和completeWork方法
beginWork
completeWork
beginWork: 该方法会根据传入的Fiber节点创建子Fiber节点,并将这两个Fiber节点连接起来。
子Fiber节点
当遍历到叶子节点(即没有子组件的组件)时就会进入“归”阶段。
completeWork:当某个Fiber节点执行完completeWork,如果其存在兄弟Fiber节点(即fiber.sibling !== null),会进入其兄弟Fiber的“递”阶段。如果不存在兄弟Fiber,会进入父级Fiber的“归”阶段。
兄弟Fiber节点
fiber.sibling !== null
兄弟Fiber
父级Fiber
function App() { return ( <div> i am <span>KaSong</span> </div> ); } ReactDOM.render(<App />, document.getElementById("root"));
React架构揭秘
本篇文章是对React Fiber架构调度器(Scheduler)、协调器(Reconciler)、渲染器(Renderer)的总结。
1.调度器
2.协调器
2.1React中定义Fiber的数据结构:
2.2“双缓存”
在React中最多会同时存在两棵Fiber树。当前屏幕上显示内容对应的Fiber树称为current Fiber树,正在内存中构建的Fiber树称为workInProgress Fiber树。
current Fiber树中的Fiber节点被称为current fiber,workInProgress Fiber树中的Fiber节点被称为workInProgress fiber,他们通过alternate属性连接。
Jsx和Fiber节点的关系
JSX
是一种描述当前组件内容的数据结构,他不包含组件schedule、reconcile、render所需的相关信息。比如如下信息就不包括在
JSX
中:优先级
state
标记
这些内容都包含在
Fiber节点
中。所以,在组件
mount
时,Reconciler
根据JSX
描述的组件内容生成组件对应的Fiber节点
。在
update
时,Reconciler
将JSX
与Fiber节点
保存的数据对比,生成组件对应的Fiber节点
,并根据对比结果为Fiber节点
打上标记
。3.渲染器
render阶段
开始于performSyncWorkOnRoot
或performConcurrentWorkOnRoot
方法的调用。这取决于本次更新是同步更新还是异步更新。在渲染阶段,使用深度优先遍历每个fiber,为每个遍历到的Fiber节点使用
beginWork
方法和completeWork
方法beginWork: 该方法会根据传入的
Fiber节点
创建子Fiber节点
,并将这两个Fiber节点
连接起来。当遍历到叶子节点(即没有子组件的组件)时就会进入“归”阶段。
completeWork:当某个
Fiber节点
执行完completeWork
,如果其存在兄弟Fiber节点
(即fiber.sibling !== null
),会进入其兄弟Fiber
的“递”阶段。如果不存在兄弟Fiber
,会进入父级Fiber
的“归”阶段。React Fiber渲染下面代码的流程:
参考资料
React架构揭秘