Fiberとは何か?
React 16で導入されたFiberアーキテクチャ。なぜ旧アーキテクチャではダメだったのか、Fiberは何を可能にしたのかを解説します。
🎯 結論から言う
Fiberとは「中断可能な作業単位」のデータ構造です。
React 16以降、すべてのコンポーネントは「Fiber」という内部オブジェクトとして管理されます。
📜 なぜStack Reconcilerではダメだったのか?
React 15以前はStack Reconcilerというアーキテクチャを使っていました。 これはJavaScriptのコールスタックを使ってコンポーネントを再帰的に処理するものでした。
Stack Reconcilerの問題
// Stack Reconcilerのイメージ(再帰で全部処理)
function reconcile(component) {
// 1つ処理したら...
const children = component.render();
for (const child of children) {
reconcile(child); // 再帰!中断できない
}
} - 再帰なので途中で中断できない
- コンポーネントが深いと処理に数十msかかる場合がある
- その間はメインスレッドがブロックされ、ユーザー入力が無視される
- 60fps(16ms/frame)を維持できない → UIがカクつく
具体的な問題例
1000件のリストを再レンダリング中にユーザーがボタンをクリックした場合、 Stack Reconcilerはリスト処理を終えるまでクリックを処理できません。 処理が50ms かかれば、ユーザーは50msの「フリーズ」を体験します。
🧵 Fiberが解決したこと
Fiberは再帰をループに変えることで、処理を任意の時点で中断・再開できるようにしました。 各コンポーネントに対応するFiberオブジェクトを連結リスト(リンクトリスト)として管理します。
interface Fiber {
// コンポーネントの種類
type: string | Function;
// propsとstate
pendingProps: Props;
memoizedState: State;
// ツリー構造(連結リスト)
child: Fiber | null; // 最初の子
sibling: Fiber | null; // 次の兄弟
return: Fiber | null; // 親
// 変更フラグ
flags: Flags; // 更新・挿入・削除
// ダブルバッファリング
alternate: Fiber | null; // 前回のFiber
} // Fiberのイメージ(ループで処理 → 中断可能)
function workLoop(deadline) {
while (nextUnitOfWork && deadline.timeRemaining() > 0) {
// 1つのFiberを処理
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
}
if (nextUnitOfWork) {
// 時間切れ → ブラウザに制御を返す(次フレームに再開)
requestIdleCallback(workLoop);
} else {
// 全Fiber処理完了 → commit phase
commitRoot();
}
} requestIdleCallback(実際はReact独自のスケジューラー)で
ブラウザが余裕のある時間帯(アイドル時間)に作業を小刻みに処理します。
ユーザー入力が来たら即座にそちらを優先できます。
🌳 ダブルバッファリング
Reactは常に2つのFiberツリーを保持します——current tree(現在の画面)と work-in-progress tree(作業中の新しいツリー)です。
現在ブラウザに表示されている状態のFiberツリー
新しい状態で構築中のFiberツリー(中断可能)
この設計により、レンダリング中(render phase)にユーザーが見ているUIは変わりません。 ブラウザへの反映はcommit phaseで一瞬で行われます。
🚀 FiberがConcurrent Modeを可能にした
Fiberアーキテクチャによって、Reactは優先度に基づいた処理スケジューリングを実現しました。
startTransitionの意味
React 18のstartTransitionは
「この更新は遅くていい」とReactに伝えるAPIです。
Fiberのスケジューラーがこの更新を低優先度として扱い、ユーザー入力の処理を先に行います。
📌 まとめ
- ✓ Stack Reconcilerは再帰処理で中断できず、複雑なUIでJankが発生していた
- ✓ Fiberは「作業単位」を連結リストで管理し、ループ処理で中断・再開を実現
- ✓ ダブルバッファリングで、ユーザーが見るUIを変えずに計算できる
- ✓ 優先度スケジューリングにより、入力など高優先度タスクを先に処理できる
- ✓ startTransitionはFiberのスケジューラーに「低優先度」を伝えるAPI