fiber 的实现原理
❤️

fiber 的实现原理

🤤
多理解

 
原答案:
fiber虚拟DOM对比的一个 diff 算法,原理不是很清楚

 
参考:
参考来源
 
FiberReact 16后实现的一个新的更新机制,它比之前的使用递归遍历每一个节点进行节点更新更快,不会长时间占用主线程,之前的性能慢的原因就是递归不会停止,使用的是 JS 引擎自身的函数调用栈,需要等到栈为空才停止,就会导致长时间占用主线程,就会阻塞浏览器 UI 的渲染,导致界面的卡顿。
Fiber 实现了自己的组件调用栈,它以链表的形式遍历组件树,可以灵活的暂停、继续和丢弃执行的任务。实现的方式和原理就是使用了浏览器的原生 APIrequestIdleCallback
window.requestIdleCallback() 会在浏览器空闲时期依次调用函数,这就可以让开发者在主事件循环中执行后台或低优先级的任务,而且不会对像动画和用户交互这些延迟触发但关键的事件产生影响。函数一般会按先进先调用的顺序执行,除非函数在浏览器调用它之前就到了它的超时时间。
 

Fiber 主要解决了两个问题

1. 保证任务在浏览器空闲时执行

依赖浏览器提供的 API requestIdleCallback() 实现任务调度 -- 优先级高的任务优先执行,优先级低的任务尽量在浏览器空闲时执行。
requestIdleCallback(callback)浏览器空闲时会执行传入的回调函数,回调函数接收一个deadline 对象,该对象的 timeReamaining() 方法可以获取到浏览器的空闲时间,如果有空闲时间,就执行一段小任务,如果时间不足了,就等待执行。
为了达到这种效果,就需要有一个调度器 (Scheduler) 来进行任务分配。任务的优先级有六种:
  • synchronous,与之前的操作一样,同步执行
  • task,在 next tick 之前执行
  • animation,下一帧之前执行
  • high,在不久的将来立即执行
  • low,稍微延迟执行也没关系
  • offscreen,下一次 render 时或 scroll 时才执行

2. 任务碎片化

链表结构
由于虚拟 DOM 树结构,被打断后无法恢复之前任务继续执行,所以需要一种新的数据结构,即链表结构,链表可以包含多个指针,可以轻松找到下一个节点,从而恢复任务执行。Fiber 采用的链表包含 3 个指针,return 指向父 Fiber 节点,child 指向 大儿子Fiber 节点,sibling 指向兄弟 Fiber 节点。一个 Fiber 节点对应一个任务节点。
Fiber 具体实现:
Fiber Reconciler 在阶段一进行 Diff 计算的时候,会生成一棵 Fiber 树。这棵树是在 Virtual DOM 树的基础上增加额外的信息来生成的,它本质来说是一个链表。
Fiber 树在首次渲染的时候会一次过生成。在后续需要 Diff 的时候,会根据已有树和最新 Virtual DOM 的信息,生成一棵新的树。这颗新树每生成一个新的节点,都会将控制权交回给主线程,去检查有没有优先级更高的任务需要执行。如果没有,则继续构建树的过程。
如果过程中有优先级更高的任务需要进行,则 Fiber Reconciler 会丢弃正在生成的树,在空闲的时候再重新执行一遍。
在构造 Fiber 树的过程中,Fiber Reconciler 会将需要更新的节点信息保存在 Effect List 当中,在阶段二执行的时候,会批量更新相应的节点。