【前端架构和框架】react工作两大循环

122 阅读3分钟

本篇我们看下react调度和协调阶段两大工作循环,本系列文章旨在分析react核心模块内部运行原理和源码实现,提升架构和编码能力。

下图是我从社区看到的,整体上基本的核心流程全部都画出来了,我们的目的是弄懂react核心运行流程,就对着下图来分析。 684cde13-93ae-46ad-9ce4-b664a7135684.jfif

前文中已经介绍过react整体架构,这里从图上可以看出react几大核心模块之间的调用关系:

  • Scheduler

    调度机制核心实现,从图中看出对外提供unstable_scheduleCallback方法,该方法用于以某个优先级注册回调函数。其实就是注册的performConcurrentWorkOnRoot函数,代表一个task,注册后任务队列重新按照优先级排序,然后调度requestHostCallback函数发起MessageChannel宏任务,下一帧在宏任务回调函数中执行workloop任务循环,先从优先级最高的任务开始调度。这就是两大循环之一的任务调度循环

  • reconciler

react核心包,react中80%的代码量都来自这个包,接收react-dom中通过setState或者初始化等产生的schedulerUpdateOnFiber,然后调用调度器的入口函数ensureRootIsScheduled,根据不同的优先级,触发同步更新还是异步更新,同步更新直接进入render阶段入口performSyncWorkOnRoot进行fiber树的workloop循环构建;异步更新则先进入调度器Scheduler注册任务performConcurrentWorkOnRoot(也是render入口),调度器到期调度task,然后进入fiber树的workloop循环构建。这里面两大循环之一的fiber构建循环

关系和不同

  1. 关系

    • 大循环套小循环的关系,任务调度循环中的每一个任务task都是一个fiber构造循环,它们是从属关系, 每个任务都会重新构造一个fiber树。从而完成异步可中断更新。
  2. 不同

    • 任务调度循环是以最小顶堆为数据结构,堆顶是优先级最高的任务,循环执行堆的顶点,直到堆被清空。

    • fiber构造循环是以链表链接的树形结构, 从rootFiber开始向下深度优先遍历,遍历到的每个Fiber节点调用beginWork和completeWork阶段完成`update队列,状态计算,调和算法,创建子fiber等,完成整体fiber的构建。

整体逻辑

通过上文的描述, 两大循环的分工可以总结为: 大循环(任务调度循环)负责调度task, 小循环(fiber 构造循环)负责实现task .

react运行的整体逻辑, 实际上就是围绕这两大工作循环进行展开,结合上图, 可以将react运行的整体逻辑进行概括:

  1. 提交更新: 将每一次更新setState,setReducer视为一次更新需求,产生schedulerUpdateOnFiber。

  2. 注册任务: react-reconciler收到更新需求之后,判断同步更新还是异步更新,进入是直接进入协调阶段构建fiber树吗,还是去调度中心scheduler注册一个新任务task,即把更新需求转换成一个task

  3. 调度任务: 调度中心scheduler通过任务调度循环按照优先级调度task,高优先级任务可以打断低优先级任务,被中段的任务不会从任务队列中移除,后续帧中再次拿出来调度(时间分片耗尽让出,还是高优先级打断)

    • fiber构造循环task的实现环节之一, 循环完成之后会构造出最新的 fiber 树.
    • commitRoottask的实现环节之二, 把最新的 fiber 树最终渲染到页面上, task完成.

任务调度循环fiber构造循环相互配合就可以实现异步可中断渲染.

总结

本文从整体流程上描述了react源码中的两大工作循环。通过这两个大循环我们大了解了react运行的整体逻辑。方便我们后续看源码打下铺垫。