mini-react 第二天:实现Fiber任务调度器

目的:将整棵树的render拆分成小任务避免页面卡顿

模拟卡顿:在document.append 后面加一个1个亿的 while counter

workLoop

工作机制类似于一个message queue和一个消费者

  • Message queue: 根据vdom树生成的fiber树双向链表
  • 消费者:workLoop 这个while循环
javascript 复制代码
// 对于workLoop来讲,即将执行的任务(即将处理的vdom节点)
let nextWorkOfUnit = null;


function workLoop(deadline) {
  let shouldYield = false;
  while (!shouldYield && nextWorkOfUnit) {
    nextWorkOfUnit = performWorkOfUnit(nextWorkOfUnit);

    shouldYield = deadline.timeRemaining() < 1;
  }

  requestIdleCallback(workLoop);
}


function render(el, container) {
  // 将vdom的根节点作为children,创建到 root container 上
  // 这是第一个入队的任务
  nextWorkOfUnit = {
    dom: container,  // root container dom是dom树的根节点
    props: {
      children: [el],
    },
  };
}

实现Fiber 架构

在render vdom的同时,按照双向链表结构记录当前的work节点和下一个节点

注意: fiber树仅仅是一个逻辑概念,在实现代码时,只会按照逻辑顺序逐个处理每一个节点。并不会保存一个fiber树的数据。而dom树本身就是一个树状结构。

处理一个vdom节点的核心代码逻辑

javascript 复制代码
function performWorkOfUnit(fiber) {
  // 将vdom节点转换为dom节点
  // 如果vdom节点对应的dom节点未被创建,先创建dom节点,并append到父节点的dom上
  if (!fiber.dom) {
    const dom = (fiber.dom = createDom(fiber.type));

    fiber.parent.dom.append(dom);

    updateProps(dom, fiber.props);
  }

  // 将vdom的children转换为fiber节点,并链接sibling关系
  initChildren(fiber)

  console.log(fiber);

  // 4. 返回下一个要执行的任务
  if (fiber.child) {
    return fiber.child;
  }

  if (fiber.sibling) {
    return fiber.sibling;
  }

  return fiber.parent?.sibling;
}
  • 在react v16.9.0 源代码中,关于child,sibling,parent 的处理逻辑在 /packages/react-reconciler/src/ReactFiberWorkLoop.js 中的 completeUnitOfWork 函数中。在源码中寻找构建父子兄弟节点关系的部分并不容易,但是通过源码的代码注释我们可以找到相关逻辑:
javascript 复制代码
function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {
  // Attempt to complete the current unit of work, then move to the next
  // sibling. If there are no more siblings, return to the parent fiber.
  workInProgress = unitOfWork;
  do {
   ...
   // v16 源码中,parent实际命名为 return
    const returnFiber = workInProgress.return;
相关推荐
qetfw6 分钟前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
鱼毓屿御2 小时前
从「只会聊」到「边想边做」的跃迁
前端·学习·react.js
嘟嘟07173 小时前
搞懂 useState 从原生 DOM 到 React 惰性初始化的完整链路
前端·react.js·编程语言
先吃饱再说6 小时前
React 组件设计:从 Props 传递到组件封装
前端·react.js
小月土星8 小时前
React 状态管理核心原理:从批量 DOM 到派生状态
react.js
烬羽9 小时前
AI 写代码总翻车?试试"先画图再砌墙"的 Vibe Coding 三步法
react.js·ai编程·vibecoding
光影少年10 小时前
react navite 页面跳转、传参、路由监听、导航栏自定义
前端·react native·react.js
LaughingZhu11 小时前
Product Hunt 每日热榜 | 2026-07-23
前端·神经网络·react.js·搜索引擎·前端框架
不好听61311 小时前
Fragment:React 的 `<></>` 和原生的 DocumentFragment,同名不同命
前端·react.js·dom
不好听61312 小时前
useState 完全解析:初始化、异步更新、以及为什么传函数能解决闭包问题
前端·react.js