Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
观察 React 如何在协调过程中使用深度优先搜索遍历 Fiber 树。
Fiber 是 React 的内部协调引擎,在 React 16 中引入。应用中的每个组件都有一个对应的 Fiber 节点 — 一个 JavaScript 对象,存储组件类型、props、state、关联的 DOM 节点,以及指向父节点、子节点和兄弟节点的指针。这种链式结构使 React 能够在多个帧之间暂停、恢复和调度工作。
当 React 渲染组件树时,它为每个元素创建一个 Fiber 节点。节点存储:type(函数/类/字符串)、props、state、effect hooks,以及上一次渲染的 work-in-progress 状态。
与递归调用栈不同(无法暂停),Fiber 以链表形式连接:每个节点有 child 指针(第一个子节点)、sibling 指针(下一个兄弟节点)和 return 指针(父节点)。这使 React 可以迭代地遍历树。
React 以深度优先方式遍历 Fiber 树。向下时调用 beginWork(父 → 子),向上时调用 completeWork(子 → 父)。这种双遍历方式让 React 自底向上构建 effect 列表。
React 同时维护两棵 Fiber 树:current 树(屏幕上显示的)和 work-in-progress 树(正在构建的)。每个 Fiber 节点都有一个 alternate 指针连接另一棵树中的对应节点。
当 commit 阶段完成后,React 通过将根节点的 current 指针指向 work-in-progress 树来原子性地交换两棵树。旧的 current 树成为下次渲染的新 work-in-progress 树。
代表一个组件工作单元的 JS 对象。包含 type、key、ref、props、state、hooks 列表、effect 标签和树指针。
协调过程中正在构建的 Fiber 树。在 commit 阶段完成并与 current 树交换之前,用户不可见。
React 遍历 Fiber 树时调用的两个函数。beginWork 在向下时处理节点;completeWork 在向上时最终化节点。
Fiber 节点上的位掩码标志,指示需要执行的 DOM 操作:Placement(插入)、Update(更新属性)、Deletion(删除)。
每个 Fiber 都有一个 alternate 字段,指向另一棵树(current ↔ work-in-progress)中的对应节点。实现双缓冲机制。
1// Simplified Fiber node structure (React internals)2{3 tag: FunctionComponent, // type of fiber4 type: MyComponent, // component function/class/string5 key: null,6 ref: null,7 pendingProps: { id: 1 },8 memoizedProps: { id: 1 }, // props from last render9 memoizedState: hooksList, // linked list of hooks1011 // Tree pointers12 return: parentFiber, // parent13 child: firstChildFiber, // first child14 sibling: nextSiblingFiber, // next sibling1516 // Double buffering17 alternate: workInProgressFiber,1819 // Work tracking20 flags: Update | Passive, // effect tags21 lanes: DefaultLane, // priority22}
Fiber 架构使 React 的并发特性成为可能。由于工作以数据结构(而非调用栈)的形式表示,React 可以在任意 Fiber 节点处暂停协调,将控制权交还给浏览器处理用户输入等高优先级任务,然后从上次中断处恢复。这是 Suspense、transitions 和自动批处理的基础。
Your dashboard app freezes for 200ms when a user opens a settings panel. React DevTools Profiler shows a long 'Render' phase but you can't identify which component is slow.
Without understanding Fiber, the profiler's flame graph (which shows fiber-by-fiber render times) looks like random colored bars. You don't know why some components are 're-rendered' when their props haven't changed.
Understanding that each bar in the Profiler IS a fiber node helps you trace the work loop: parent → child → sibling. You can identify which fiber's `beginWork` is slow, check its `memoizedProps` vs `pendingProps`, and apply React.memo or useMemo precisely.
Takeaway: The React DevTools Profiler is literally a fiber tree visualizer. Understanding fiber architecture transforms it from a confusing chart into a powerful debugging tool.
You have a drag-and-drop interface where moving an item should animate at 60fps, but data fetching from a heavy table re-render causes janky movement.
A single synchronous render blocks the main thread for 50ms+, causing the browser to skip animation frames during the data fetch re-render.
React Fiber's priority lanes system lets you wrap the heavy re-render in `startTransition()`, marking it as low-priority. The fiber work loop can now pause the heavy render, yield to the browser for animation frames, and resume later — all because fibers are interruptible units of work.
Takeaway: Fiber architecture is the reason `useTransition` and `useDeferredValue` exist. These APIs wouldn't be possible without interruptible, priority-based rendering.