React Fiber 原理

React Fiber

在 React 16 之前的版本对比更新 VirtualDOM 的过程是采用 Stack 架构实现的,也就是循环加递归,这种方式的问题是一旦任务开始进行就无法被中断。

如果应用中的组件数量庞大, Virtual DOM 的层级比较深,主线程被长期占用,直到整棵 Virtual DOM 树比对更新完成之后主线程才能被释放,主线程才能执行其他的任务,这会导致一些用户交互,动画等任务无法得到立即执行,页面会卡顿,非常影响用户体验。

核心问题是:递归无法被中断,执行任务耗时长,JavaScript 是单线程的,和 Native GUI 互斥,比较 VirtualDOM 的过程中无法执行其他任务,导致任务延迟页面卡顿,用户体验差。

Fiber 的思路

  1. 放弃递归调用,采用循环模拟递归,因为循环可以被随时中断
  2. Fiber 将大的渲染任务拆分成一个个小任务(Fiber节点的创建)
  3. React 使用 window.requestIdleCallback 去利用浏览器的空闲时间去执行小任务,React 在执行一个任务单元后,查看是否有其他高优先级的任务,如果有,放弃占用线程,先执行优先级高的任务

关于 window.requestIdleCallback 的作用,可以查看 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback ,例子可以查看 https://github.com/zjy4fun/requestIdleCallback

Fiber 的结构

// 简易版 Fiber 对象
type Fiber = {
  // 组件类型 div、span、组件构造函数
  type: any,
  // DOM 对象
  stateNode: any,  
  // 指向自己的父级 Fiber 对象
  return: Fiber | null,
  // 指向自己的第一个子级 Fiber 对象
  child: Fiber | null,
  // 指向自己的下一个兄弟 iber 对象
  sibling: Fiber | null,
}

Fiber 两阶段

Render

构建 Fiber 对象,构建链表,在链表中标记要执行的 DOM 操作 ,可中断。

Commit

根据构建好的链表进行 DOM 操作,不可中断。

参考

https://juejin.cn/post/6993973502852202503

posted @ 2024-10-07 18:49  zjy4fun  阅读(20)  评论(0编辑  收藏  举报