第一章:理念篇
设计理念
-
设计理念:快速响应
-
突破瓶颈:
- cpu
- I/O
-
解决方案:异步可中断更新
架构的演进史
老的React架构(React15架构)
React15架构可以分为两层
Reconciler(协调器)—— 负责找出变化的组件Renderer(渲染器)—— 负责将变化的组件渲染到页面上
Reaconciler(协调器)- 每当有更新发生的时候,
Reconciler会做以下工作:- 调用函数组件、或
class组件的render方法,将返回的JSX转化为虚拟DOM - 将虚拟DOM和上次更新时的虚拟DOM对比
- 通过对比找出本次更新中变化的虚拟DOM
- 通知
Renderer将变化的虚拟DOM渲染到页面上
- 调用函数组件、或
- 每当有更新发生的时候,
Renderer(渲染器)- 浏览器环境渲染的
Renderer——ReactDOM ReactNative渲染器,渲染APP原生组件ReactTest渲染器,渲染出纯Js对象用于测试ReactArt渲染器,渲染到Canvas、SVG或VML(IE8)
- 浏览器环境渲染的
React15架构的缺点
- 在
Reconciler中,mount的组件会调用mountComponent,update的组件会调用updateComponent。这两个方法都会递归更新子组件。
递归更新的缺点
- 由于递归执行,所以更新一旦开始,中途无法中断。当层级很深时,递归更新超过了16ms,用户交互就会卡顿。
举个例子:
+ 页面同时更新1,2,3
+ +1
+ 第一次点击,后`Reconciler`协调器发现1要变为2,此时通知`Renderer`更新DOM,1变为2
+ 依次执行
+ 问题发生,当此时1,2,3未全部更新完毕,发生异步中断更新,
+ 页面会看到数据更新为2,2,3
> 因此,React,重写架构。
新的React架构(React16架构)
React16架构可以分为三层
Scheduler(调度器)—— 调度任务的优先级,高级任务先进入ReconcilerReconciler(协调器)Renderer(渲染器)
与React15架构相比,React16新增了
Reconciler(调度器)。
反观例子
Scheduler运行- 点击button,产生一个更新,更新内容1 --> 2
Scheduler,接收到更新,看一下是否有更高优先级的更新需要先执行?- 若无,将1-->2 交给
Reconciler
Reconciler运行- 接收到更新,看下造成了哪些虚拟DOM的更新
- 将1,2,3,全部打上
update标记 - 无其他变化,将打上标记的虚拟DOM交给
Renderer
Renderer运行- 接收到通知,看下哪些被打了标记的虚拟DOM
- 有三个打了标记,进行更新DOM的操作
Scheduler和Reconciler的运行,可以被中断:- 有没有其他更高优先级的任务需要更新
- 当前帧没有剩余时间
- 由于红框中的工作都在内存中进行,不会更新页面上的DOM,所以即使反复中断,用户也不会看见更新不完全的DOM
Reconciler内部采用了Fiber的架构。
Fiber架构与代数效应的关系
- 代数效应:将副作用从函数调用逻辑中分离
- async await, 具有传染性,破坏了同步特性
- try catch 执行完 栈中被销毁
- react 与 代数效应 的区别:hooks:不关系数据存储,只关心更新
- fiber思想就是一种 异步可中断更新
- 中断、恢复的思想
- 这是 fiber 纤程
- generator,
- 与 async await一致,有传染性
- 更新可中断并继续、更新有不同优先级,高优先级可以打断低优先级(达不到)