学习二十五、React 架构

react 16版本的架构可以分为三层:调度层、协调层、渲染层

  • Scheduler 调度层: 调度任务的优先级、高优任务优先进入协调层
  • Reconciler 协调层: 构建 fiber 数据结构,比对 fiber 对象找出差异,记录 fiber 对象要进行的 DOM 操作
  • renderer 渲染层: 负责将发生变化的部分渲染到页面上

Scheduler 调度层

在 React 15 的版本中,采用了循环加递归的方式进行了 virtualDOM 的比对,由于递归使用 javascrip 自身的执行栈,一旦开始就无法停止,知道任务执行完成。如果 virtualDOM 树的层级比较深, virtualDOM 的比对就会长期占用 javascript 主线程,由于 javascrip 又是单线程的无法同时执行其他任务,所以在比对的过程中无法相应用户操作,无法立即执行元素动画,造成了页面卡顿。

在 React 16 的版本中, 放弃了 javascript 递归的方式进行 virtualDOM 的比对,而是采用循环模拟递归,而且比对的过程是利用浏览的空闲时间完成,不会长期占用主线程,这就解决了 virtualDOM 比对造成页面卡顿的问题。

在 window 对象中提供了 requestIdleCallback API,他可以利用浏览器的空闲时间执行任务,但是他自身也存在一些问题,比如说并不是所有的浏览器都支持它,而且它的触发频率也不是很稳定,所以react最终放弃了 requestIdleCallback 放入使用。

在 react 中,官方实现了自己的任务调库,这个库就叫做 Scheduler,他可以实现在浏览器空闲时执行任务,而且还可以设置任务的优先级,优先级高的任务先执行,优先级低的任务后执行。

Scheduler 存储在 packages/sheduler文件夹中

Reconciler 协调层

在 React 15 的版本中,协调器和渲染器交替执行,即找到了差异就直接更新差异,在 react 16 的版本中,这种情况发生了变化,协调器和渲染器不再交替执行,协调器负责找出差异,在所有差异找出之后,统一交给渲染器进行 DOM 的更新,也就是说协调器的主要任务就是找出差异的部分,并为差异搭上标记。

Renderer 渲染层

渲染器根据协调器为 fiber 节点打的标记,同步执行对应的DOM操作。

既然你比对的过程从递归变成了可以中断的循环,那么 react 是如何解决中断更新时 DOM渲染不完全的问题呢?

其实根本就不存在这个问题,因为在整个过程中,调度器和协调器的工作是在内存中完成的是可以被打断的,渲染器的工作被设定成不可以被打断,所以不存在 DOM 渲染不完全的问

猜你喜欢

转载自blog.csdn.net/qq_40289624/article/details/113185445