深入理解React – 5 – Fiber

React Fiber架构

React在16.3之后引入了Fiber架构。

我们知道生命周期主要有三个阶段,即渲染阶段,调和阶段,提交阶段。

在引入fiber结构之前,React的diff算法是采用深度优先遍历(DFS)的算法,是一个递归的过程,当DOM结构复杂时调和需要的时间过长,会导致js主线程被长时间占用,因此会出现卡顿,交互无反应等问题。 为了解决这个问题才引入了fiber架构。

就是在调和阶段将原来的栈调和(stack reconcilation) 改为新的fiber调和。

调和和diff算法有什么关联呢?

调和就是指将实际DOM按照虚拟DOM渲染成一致的过程, 而diff算法只是这个过程中的一个步骤,也就是说调和是包含diff算法的。

fiber架构的diff算法主要从以下几点进行了突破

  1. 采用分层对比,只对同级的元素进行diff比较,如果dom元素跨越了层级,就默认不再能复用了
  2. 不同类型的元素会react会直接销毁当前节点及子节点,创建新的节点
  3. 通过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算法是对比两棵树的区别


Posted

in

by

Tags: