书籍传送门: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
瓶颈:网络延迟给用户造成的视觉感知;
答案:”时间切片”。—– 将同步的更新变成可中断的异步更新。
问题:
- 同步的更新是针对于谁而言?
React 15
而言。
- 异步的更新中断后去做了什么?做完之后又干了什么?
- 更新中断后,把控制权交给主线程去
Update
,做完之后检测是否有空闲时间,再去接着执行上一次中断后的任务。中断过程是发生在内存中的,所以用户不会有任何感知
- 更新中断后,把控制权交给主线程去
- 什么时候会中断?
- 有高优先任务进入;
- 当前帧无剩余时间;
React 架构篇
React 15 架构
Reconciler
协调器,负责变化的组件。Renderer
渲染器,负责将变化的组件渲染到页面中。
mountComponent
&updateComponent
时,都会递归组件。
递归开始,中途无法中断,当层级很深时,递归更新时间超过了316ms,用户交互就会明显感觉卡顿;
React15
的Reconciler
做了什么?
Reconciler
和Renderer
交替执行,通过递归挂载dom
树。
React 16架构
Scheduler
(调度器)—调度高优任务进入Reconciler
。核心应该是后边的lans
Reconciler
(协调器)—-负责找出变化的组件,并diff
生成新的DOM
结构Renderer
(渲染器)—-负责将变化渲染到页面上
整个scheduler
和reconciler
都是在内存中进行的,只有当所有组件都完成Reconciler
的工作,才会统一交给Renderer
的去处理。
笔者阅读此处曾有过疑问:【中断是何时开始的?中断的是commit
截断还是render
阶段?会中断render
任务吗?】
其实答案已经在文章中了,此处只是略作记录~
Reconciler
会为虚拟DOM(fiber)
打标记(增
、删
、改
、hooks
等);
Renderer
会根据虚拟DOM
中的标记,对真实DOM
进行操作(同步执行);
Fiber 架构
读到这里,笔者跟大家其实都有同一个疑问:什么是Fiber
?
- 架构维度
stack reconciler
(React 15
) —->fiber reconciler
(React 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] JSX
与Fiber
有什么关系?
mount
和update
,都会根据对应的jsx
数据结构,生成对应的fiber
节点,fiber
也是一种数据结构。
[3] React Element
和React Component
是什么关系?
参考:React 探秘 - React Component 和 Element(文末附彩蛋demo和源码)
- 使用
React Component
来生成React Element
,但是不一定返回的是一定是React Element
,也有可能是null
。- 当写
JSX
时,babel
会自动转译JSX
为React Element
. React Component
分为:Class Component
&Function Component
;
- 当写