愿我如星君如月,夜夜流光相皎洁。
React 核心
1 | const state = reconcile(update); |
React15 架构
- React15 架构分两层
- Reconciler(协调器) 负责找出变化的组件
React中可以通过this.setState、this.forceUpdate、ReactDOM.render等API触发更新。每当有更新发生时,Reconciler会做如下工作:
(1). 调用函数组件、或class组件的render方法,将返回的JSX转化为虚拟DOM
(2). 将虚拟DOM和上次更新时的虚拟DOM对比
(3). 通过对比找出本次更新中变化的虚拟DOM
(4). 通知Renderer将变化的虚拟DOM渲染到页面上
- Renderer(渲染器) 负责将变化的组件渲染到页面上
在每次更新发生时,Renderer接到Reconciler通知,将变化的组件渲染在当前宿主环境
React支持跨平台,所以不同平台有不同的Renderer,负责在浏览器环境渲染的Renderer —— ReactDOM (opens new window)。
(1). ReactNative (opens new window)渲染器,渲染App原生组件
(2). ReactTest (opens new window)渲染器,渲染出纯Js对象用于测试
(3). ReactArt (opens new window)渲染器,渲染到Canvas, SVG 或 VML (IE8)
React15架构的缺点
- 在Reconciler中,mount的组件会调用mountComponent (opens new window),update的组件会调用updateComponent (opens new window)。这两个方法都会递归更新子组件。
- 由于递归执行,所以更新一旦开始,中途就无法中断。当层级很深时,递归更新时间超过了16ms,用户交互就会卡顿。
- 中断情况下
React16架构
- React16架构分为三层
- Scheduler(调度器)
- 调度任务的优先级,高优任务优先进入Reconciler
- 部分浏览器已经实现了这个API,就是requestIdleCallback,由于兼容和触发,React实现了功能更完备的requestIdleCallbackpolyfill,这就是Scheduler
- Reconciler(协调器)
- 负责找出变化的组件
- React15中Reconciler是递归处理虚拟DOM的,React更新工作从递归变成了可以中断的循环过程
1 | /** @noinline */ |
- React16中,Reconciler与Renderer不再是交替工作。当Scheduler将任务交给Reconciler后,Reconciler会为变化的虚拟DOM打上代表增/删/更新的标记
1 | export const Placement = /* */ 0b0000000000010; |
- 整个Scheduler与Reconciler的工作都在内存中进行。只有当所有组件都完成Reconciler的工作,才会统一交给Renderer。可以解决React 中断更新时DOM渲染不完全的问题。
- Renderer(渲染器)
- 负责将变化的组件渲染到页面上
React16架构更新流程
- 红框内容可中断,在内存中进行,不会更新页面DOM,反复中断用户也看不到DOM更新