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 16で導入された、Reactの内部リコンシリエーションエンジンです。アプリ内の各コンポーネントには対応するFiberノードがあります。これはコンポーネントの型、props、state、関連するDOMノード、そして親・子・兄弟Fiberへのポインタを格納するJavaScriptオブジェクトです。このリンク構造により、Reactは複数のフレームをまたいで作業を一時停止・再開・優先順位付けすることができます。
Reactがコンポーネントツリーをレンダリングするとき、各要素に対してFiberノードを作成します。ノードには次の情報が格納されます:型(関数・クラス・文字列)、props、state、エフェクトフック、および前回のレンダリングからの作業中の状態。
一時停止できない再帰的なコールスタックとは異なり、Fiberはリンクリストとして接続されています。各ノードには子ポインタ(最初の子)、兄弟ポインタ(次の兄弟)、returnポインタ(親)があります。これによりReactはツリーを反復的に走査できます。
Reactは深さ優先でFiberツリーを走査します。下方向(親→子)では「beginWork」を呼び出し、上方向(子→親)では「completeWork」を呼び出します。この2パスのアプローチにより、Reactはエフェクトリストをボトムアップで構築できます。
Reactは2つのFiberツリーを同時に維持します:「current」ツリー(画面に表示中のもの)と「work-in-progress」ツリー(構築中のもの)。各Fiberノードにはもうひとつのツリーのカウンターパートを指す「alternate」ポインタがあります。
コミットフェーズが完了すると、Reactはルートの「current」ポインタをwork-in-progressツリーに向けることで、2つのツリーをアトミックに入れ替えます。古いcurrentツリーは次のレンダリングの新しいwork-in-progressになります。
コンポーネントの1つの作業単位を表すJSオブジェクト。型、key、ref、props、state、hooksリスト、エフェクトタグ、ツリーポインタを含みます。
リコンシリエーション中に構築されるFiberツリー。コミットフェーズが完了してcurrentツリーと入れ替わるまで、ユーザーには見えません。
ReactがFiberツリーを走査する際に呼び出す2つの関数。beginWorkは下方向にノードを処理し、completeWorkは上方向に戻りながらノードを確定します。
Fiberノード上のビットマスクフラグで、必要なDOM操作を示します:Placement(挿入)、Update(propsのパッチ適用)、Deletion(削除)。
各Fiberは、もうひとつのツリー(current ↔ work-in-progress)のカウンターパートを指す「alternate」フィールドを持ちます。ダブルバッファリングを実現します。
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、トランジション、自動バッチ処理の基盤です。
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.