React Fiber架构
React在16.3之后引入了Fiber架构。
我们知道生命周期主要有三个阶段,即渲染阶段,调和阶段,提交阶段。
在引入fiber结构之前,React的diff算法是采用深度优先遍历(DFS)的算法,是一个递归的过程,当DOM结构复杂时调和需要的时间过长,会导致js主线程被长时间占用,因此会出现卡顿,交互无反应等问题。 为了解决这个问题才引入了fiber架构。
就是在调和阶段将原来的栈调和(stack reconcilation) 改为新的fiber调和。
调和和diff算法有什么关联呢?
调和就是指将实际DOM按照虚拟DOM渲染成一致的过程, 而diff算法只是这个过程中的一个步骤,也就是说调和是包含diff算法的。
fiber架构的diff算法主要从以下几点进行了突破
- 采用分层对比,只对同级的元素进行diff比较,如果dom元素跨越了层级,就默认不再能复用了
- 不同类型的元素会react会直接销毁当前节点及子节点,创建新的节点
- 通过key属性来帮助diff分辨哪些元素需要更新
React Fiber架构有哪些优点呢?
三大优点,可中断,可恢复,优先级
fiber中增加了一个scheduler
- 每个更新任务都会被赋予一个优先级
- 如果发现B任务的优先级高于当前任务A,那么任务A就会被中断(可中断)
- 优先进行B任务的渲染
- 再讲A推入Reconciler层,继续渲染(可恢复)
详细说下可中断和可恢复,在插入一个优先级更高的任务时,传统树需要把后边所有未处理的任务保存起来,这会带来很大的开销,而fiber树只需要把当前节点记录在一个变量里就可以了,下次更新可以按照逻辑先遍历自己,再child, 再siblings
优先级 child -> siblings -> return
这里有两个处理方式,从beginWork开始,向下面的children寻找是调用beginWork,当没有子节点时,调用completeUnitOfWork回到兄弟节点

Fiber树
Fiber树和传统树有很大的不同,父节点只和他的第一个子节点相连接,而第一个子节点和后边的兄弟节点相连接,每个孩子都有一个指向父亲节点的指针,这样构成了一个单向链表的结构
Fiber树有新旧两个树,即current tree和workInProgress tree
current tree 存储当前页面中每个组件状态
更新节点时,根据current tree和一些修改过的参数形成 workInProgress tree。
最终React将workInProgress tree渲染到页面,再把他复制成current tree。
在构建current树时,是边构建边diffing的,如果构建到一半被打断,那么current树还在,如果构建完成了则删除掉current树,workInProgress树成为新的current树
所以说旧的diff算法是对比虚拟DOM和真实DOM的区别,fiber的diff算法是对比两棵树的区别