You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/** @noinline */functionworkLoopConcurrent(){// Perform work until Scheduler asks us to yieldwhile(workInProgress!==null&&!shouldYield()){workInProgress=performUnitOfWork(workInProgress);}}
查看原文
React15架构
React15架构可以分为两层:
#Reconciler(协调器)
我们知道,在
React
中可以通过this.setState
、this.forceUpdate
、ReactDOM.render
等API触发更新。每当有更新发生时,Reconciler会做如下工作:
render
方法,将返回的JSX转化为虚拟DOM#Renderer(渲染器)
由于
React
支持跨平台,所以不同平台有不同的Renderer。我们前端最熟悉的是负责在浏览器环境渲染的Renderer —— ReactDOM (opens new window)。除此之外,还有:
在每次更新发生时,Renderer接到Reconciler通知,将变化的组件渲染在当前宿主环境。
#React15架构的缺点
在Reconciler中,
mount
的组件会调用mountComponent (opens new window),update
的组件会调用updateComponent (opens new window)。这两个方法都会递归更新子组件。#递归更新的缺点
由于递归执行,所以更新一旦开始,中途就无法中断。当层级很深时,递归更新时间超过了16ms,用户交互就会卡顿。
在上一节中,我们已经提出了解决办法——用可中断的异步更新代替同步的更新。那么React15的架构支持异步更新么?让我们看一个例子:
乘法小Demo
我用红色标注了更新的步骤。
我们可以看到,Reconciler和Renderer是交替工作的,当第一个
li
在页面上已经变化后,第二个li
再进入Reconciler。由于整个过程都是同步的,所以在用户看来所有DOM是同时更新的。
接下来,让我们模拟一下,如果中途中断更新会怎么样?
注意
以下是我们模拟中断的情况,实际上
React15
并不会中断进行中的更新当第一个
li
完成更新时中断更新,即步骤3完成后中断更新,此时后面的步骤都还未执行。用户本来期望
123
变为246
。实际却看见更新不完全的DOM!(即223
)基于这个原因,
React
决定重写整个架构。React16架构
React16架构可以分为三层:
可以看到,相较于React15,React16中新增了Scheduler(调度器),让我们来了解下他。
#Scheduler(调度器)
既然我们以浏览器是否有剩余时间作为任务中断的标准,那么我们需要一种机制,当浏览器有剩余时间时通知我们。
其实部分浏览器已经实现了这个API,这就是requestIdleCallback (opens new window)。但是由于以下因素,
React
放弃使用:requestIdleCallback
触发的频率会变得很低基于以上原因,
React
实现了功能更完备的requestIdleCallback
polyfill,这就是Scheduler。除了在空闲时触发回调的功能外,Scheduler还提供了多种调度优先级供任务设置。#Reconciler(协调器)
我们知道,在React15中Reconciler是递归处理虚拟DOM的。让我们看看React16的Reconciler (opens new window)。
我们可以看见,更新工作从递归变成了可以中断的循环过程。每次循环都会调用
shouldYield
判断当前是否有剩余时间。那么React16是如何解决中断更新时DOM渲染不完全的问题呢?
在React16中,Reconciler与Renderer不再是交替工作。当Scheduler将任务交给Reconciler后,Reconciler会为变化的虚拟DOM打上代表增/删/更新的标记,类似这样:
整个Scheduler与Reconciler的工作都在内存中进行。只有当所有组件都完成Reconciler的工作,才会统一交给Renderer。
#Renderer(渲染器)
Renderer根据Reconciler为虚拟DOM打的标记,同步执行对应的DOM操作。
所以,对于我们在上一节使用过的Demo
乘法小Demo
在React16架构中整个更新流程为:
其中红框中的步骤随时可能由于以下原因被中断:
由于红框中的工作都在内存中进行,不会更新页面上的DOM,所以即使反复中断,用户也不会看见更新不完全的DOM(即上一节演示的情况)。
#总结
通过本节我们知道了
React16
采用新的Reconciler
。Reconciler
内部采用了Fiber
的架构。Fiber
是什么?他和Reconciler
或者说和React
之间是什么关系?我们会在接下来三节解答。#参考资料
「英文 外网」Building a Custom React Renderer | React前经理Sophie Alpert(opens new window)
同步/Debounce/Throttle/并发 情况下性能对比Demo
为该章节纠错 (opens new window)
上次更新: 3/22/2021, 3:01:33 PM
← 老的React架构Fiber架构的心智模型 →
The text was updated successfully, but these errors were encountered: