书籍传送门:React技术揭秘——卡颂

前言:整篇文章,我都将以问题+笔记的形式作为精读的导语展开叙述~文末有彩蛋喔~~~

React理念篇

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

众所周知的一个概念是:JS和GUI渲染是互斥的

var arr = [1,2,3,4,5,6];
for (var i in arr) {
	setTimeout(function () {
	  console.log('i:', i);
      var newNode = document.createElement("div");
      newNode.className = 'book';
      main.appendChild(newNode);
  }, 1000 * i);
}

Demo来源:JS引擎和GUI引擎是互斥的


React解决了什么问题,如何实现?

[1] CPU瓶颈:数据渲染量大,设备性能不足,容易掉帧,造成用户视觉卡顿;
[2] IO瓶颈:网络延迟给用户造成的视觉感知;

答案:”时间切片”。—– 将同步的更新变成可中断的异步更新。

问题:

  1. 同步的更新是针对于谁而言?
    • React 15而言。
  2. 异步的更新中断后去做了什么?做完之后又干了什么?
    • 更新中断后,把控制权交给主线程去Update,做完之后检测是否有空闲时间,再去接着执行上一次中断后的任务。中断过程是发生在内存中的,所以用户不会有任何感知
  3. 什么时候会中断?
    • 有高优先任务进入;
    • 当前帧无剩余时间;

React 架构篇

React 15 架构

  • Reconciler协调器,负责变化的组件。
  • Renderer渲染器,负责将变化的组件渲染到页面中。

mountComponent&updateComponent时,都会递归组件。

递归开始,中途无法中断,当层级很深时,递归更新时间超过了316ms,用户交互就会明显感觉卡顿

React15Reconciler做了什么?

ReconcilerRenderer交替执行,通过递归挂载dom树。

React 16架构

  • Scheduler(调度器)—调度高优任务进入Reconciler核心应该是后边的 lans
  • Reconciler(协调器)—-负责找出变化的组件,并diff生成新的DOM结构
  • Renderer(渲染器)—-负责将变化渲染到页面上

整个schedulerreconciler都是在内存中进行的,只有当所有组件都完成Reconciler的工作,才会统一交给Renderer的去处理。


笔者阅读此处曾有过疑问:【中断是何时开始的?中断的是commit截断还是render阶段?会中断render任务吗?】

其实答案已经在文章中了,此处只是略作记录~


Reconciler会为虚拟DOM(fiber)打标记(hooks等);

Renderer会根据虚拟DOM中的标记,对真实DOM进行操作(同步执行);

Fiber 架构

读到这里,笔者跟大家其实都有同一个疑问:什么是Fiber

  • 架构维度
    • stack reconcilerReact 15) —-> fiber reconcilerReact 16);
  • 数据结构维度
    • 每个Fiber都对应一个React Element,记录了组件的类型和DOM信息;
  • 工作单元维度
    • 动态的WIP Fiber 树,保留了Fiber的更新信息;(WIP fiber —> current fiber

问题: 咋不叫虚拟DOM了,那现在叫啥?

原来的虚拟DOM已经更名为Fiber DOM,其实底层还是一样的思想,就是一个JS对象。描述真实DOM在内存中的形态。

Fiber 工作原理

双缓存技术:内存中构建并直接替换;

current fiber —–> wip fiber,每次update始终会创建一个新的wip fiber,使用alternate指针指向current fiber

问题: 新的wip fiber是根据旧的current fiber去构建吗?

答:答案是肯定的,wip fiber会根据旧的current fiber去构建,复用其节点数据。

深入理解JSX

[1] 什么是JSX

  • JSX是一种语法,用来描述当前组件内容的数据结构。

[2] JSXFiber有什么关系?

  • mountupdate,都会根据对应的jsx数据结构,生成对应的fiber节点,fiber也是一种数据结构。

[3] React ElementReact Component是什么关系?
参考:React 探秘 - React Component 和 Element(文末附彩蛋demo和源码)

  • 使用React Component来生成React Element,但是不一定返回的是一定是React Element,也有可能是null
    • 当写JSX时,babel会自动转译JSXReact Element.
    • React Component分为:Class Component&Function Component;

文末彩蛋:手写笔记