React15和React16的架构比较(一)

1,913 阅读2分钟

React目前已经成为前端主流框架之一,其成功原因离不开它的设计理念:

我们认为,React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方式。它在 Facebook 和 Instagram 上表现优秀。

React从版本v15升级到v16后,重构了整个架构,为什么呢?下面来对比一下v15和v16,看看React是如何进一步实现快速响应的。

React15架构

React15架构可以分为两层:

  • Reconciler(协调器)—— 负责找出变化的组件
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上

Reconciler(协调器)

Reconciler的官方解释

在开发中,我们可以通过一下几种方式触发视图更新:

  1. 初始化:render()
  2. 状态更新:setState()
  3. 强制更新:forceUpdate()

在React 15 及更早的解决方案中,协调器使用的是stack reconciler ,当React触发更新时,Reconciler会依次完成以下工作:

  • 调用函数组件、class组件的render方法,将返回的JSX转化为虚拟DOM
  • 将虚拟DOM和上次更新时的虚拟DOM对比
  • 通过对比找出本次更新中变化的虚拟DOM
  • 通知Renderer将变化的虚拟DOM渲染到页面上

Renderer(渲染器)

渲染器用于管理一棵 React 树,使其根据底层平台进行不同的调用。 由于React支持跨平台,针对不同平台有不同的Renderer:

  • ReactDOM: 负责将 React 组件渲染成 Web环境中的DOM,常用于浏览器开发中
  • ReactNative:负责将 React 组件渲染为 Native 视图,常用于native开发中
  • ReactTest:负责将 React 组件渲染为 JSON 树,常用于 Jest 的快照测试特性
  • ReactArt:负责渲染到Canvas, SVG 或 VML (IE8)

在每次更新发生时,Renderer接到Reconciler通知,将变化的组件渲染在当前开发环境。

React15的缺点

举例:初始化state.count = 1,每次点击按钮state.count++,列表中3个元素的值分别为1,2,3乘以state.count的结果。

image.png 由上图可见,Reconciler和Renderer是交替工作的,当第一个li在页面上已经变化后,第二个li再进入Reconciler。如果第二个li执行很久,那用户就会一直卡在223的页面,和预期的结果是有差别的。

在组件初始化或者更新的时候,会递归更新子组件。由于是递归执行,所以更新一旦开始,中途就无法中断。当组件层级很深时,递归更新时间超过了16.6ms(主流浏览器每16.6ms刷新一次),用户交互界面就会卡顿,用户体验较差。

于是,有了React16,请跳转React15和React16架构比较(二)