1. 虚拟dom
在学习 Fiber 之前,首先回顾下 虚拟Dom
1. 什么是虚拟Dom?
虚拟DOM可以看做一棵模拟了真实DOM树的JavaScript对象树, 它其实是一个js对象,对象中所包含的信息会告诉页面上需要渲染什么样的节点,包括及其子节点的描述信息。
但虚拟dom并不会完全复刻真实dom,虚拟dom只承载必要的信息,这也是使用虚拟dom的原因之一,因为一个真实的dom对象实际上有很多属性与方法,如果在进行diff算法时是对真实dom进行对比,会产生不必要的消耗。
2. 为什么使用 虚拟Dom?
以查找js对象的方式代替以往递归dom树的操作,将频繁更新dom的行为优先转为js对象的增删改查;通过diff算法保证最小化的DOM操作;减少重绘重排的次数。
2. React Fiber
1. 什么是 Fiber ?
Fiber 是一个分片执行单元,每执行完一个单元,React会检查现在还剩多少时间,如果没有时间则交出控制权。
Fiber是一个链表数据结构:
Child 指向 当前Fiber的第一个子节点
Sibling 指向当前Fiber的的下一个兄弟节点
Return 指向当前 Fiber 节点的 父节点
由于要实现低优先级任务的暂停更新,但是在高优先级任务执行完成之后还要回来继续执行低优先级任务,因此使用链表数据结构,通过指针和地址对任务进行关联。
2. 为什么使用 Fiber?
当 React 树太过庞大时,递归Diff会很消耗时间,会造成主线程被持续占用,有一些高优先级的任务得不到处理。因为JS单线程的原因,每个同步任务不能阻塞太长时间,因此需要对一些耗时长的任务进行分片,每一个分片所对应的数据结构就是Fiber。
高优先级任务:例如用户交互,点击或输入事件。如果点击或输入迟迟无法得到响应,用户体检一定是极差的。
3. 双缓冲结构
-
react 根据双缓冲机制维护了两个fiber树,一颗用于渲染页面 (current),一颗是 workInProgress Fiber 树,用于在内存中构建,然后方便在构建完成后直接昔换 current Fiber树
-
workInprogress Fiber 树的 alternate 指向 Current Fiber树的对应节点, current 表示页面正在使用的 fiber 树
-
当 workInprogress Fiber 树构建完成,workInProgress Fiber 则成为了 current 渲染到页面上,而之前的 current 则缓存起来成为下一次的workInProgress Fiber,完成双缓冲模型
4. 图解双缓冲结构
<div key="A">
<div key="B1"></div>
<div key="B2"></div>
</div>
A的 child 指向第一个儿子 B1,B1的 return 指向 A
B1的 sibiling指向他的兄弟 B2,B2的 return 指向 A