React重构了,从v15升级到了v17,重构了整个架构,首先我们来聊聊v15。
React15架构
对,递归的更新!所以一旦开始,Reconciler和Renderer交替工作,当递归层级很深,渲染时就出现了嘎嘣脆,渲染和交互就会卡顿,所以就有了后面我们所说的Fiber reconciler。
所以,按照这样的设计,并不能实现--用可中断的异步更新代替同步更新
React16
其实是在原有的基础上添加了Scheduler,并升级了Reconciler,采用了Fiber架构:
协同调度,我们希望当浏览器有剩余的渲染时间时来通知js线程,同时具备调度优先级任务的机制,所以就有了Scheduler,正如官网所言,这是独立库,用于在浏览器环境下协同调度
shouldYield
判断当前是否有剩余时间。/** @noinline */
function workLoopConcurrent() {
// Perform work until Scheduler asks us to yield
// 继续工作,知道Scheduler 让我们暂停
while (workInProgress !== null && !shouldYield()) {
workInProgress = performUnitOfWork(workInProgress);
}
}
同时它也做了架构上的更新:
render()
中返回多个元素。那么在渲染上做了哪些升级呢?见下图
在这个渲染过程中,Reconciler将更新的虚拟DOM打上代表增/删/更新的标记,类似这样:
// You can change the rest (and add more).
export const Placement = /* */ 0b000000000000010;
export const Update = /* */ 0b000000000000100;
export const PlacementAndUpdate = /* */ 0b000000000000110;
export const Deletion = /* */ 0b000000000001000;
export const ContentReset = /* */ 0b000000000010000;
export const Callback = /* */ 0b000000000100000;
export const DidCapture = /* */ 0b000000001000000;
export const Ref = /* */ 0b000000010000000;
Scheduler和Reconciler统一在内存中完成一系列处理以后,才交给renderer来进行渲染。
而图中大括号中的处理工作会因为浏览器中其他高级别任务或者没有剩余时间渲染而被中止(不是终止),但是由于是在内存中,所以并不会显示,等到下次帧渲染时再继续。
以上就是react架构升级的差异,当然,还有很多其他细节。