How does React's Fiber reconciliation algorithm work internally, and how does it improve rendering performance?
Fiber is a unit of work — each component instance is a Fiber node with state, refs, hooks list, and tree pointers. Reconciliation walks the fiber tree, diffs against previous, marks changes. Work is broken into chunks the scheduler can pause/resume — enabling concurrent rendering (interruption, prioritization). Replaces pre-16's synchronous stack-based reconciler.
Pre-Fiber (stack reconciler)
React 15 and earlier recursed through the component tree synchronously to produce the next DOM. If the tree was large, the main thread blocked for the entire reconcile + commit. No way to interrupt.
Fiber as a unit of work
React 16+ uses a Fiber tree — a JS data structure where each node corresponds to a component instance (or DOM element). Each Fiber holds:
{
type, key, props,
stateNode, // the DOM node / class instance
child, sibling, return,
memoizedState, // hooks linked list
memoizedProps,
alternate, // pointer to the previous fiber tree (workInProgress vs current)
effectTag, ...
}Two trees coexist during a render: the current tree (last committed) and the work-in-progress tree being built.
How reconciliation runs
- State change schedules an update.
- Scheduler picks a starting fiber and begins the render phase:
- Walk the work-in-progress tree.
- For each fiber, call the component function (or update for host elements).
- Diff against current. Mark flags (placement, update, deletion).
- The scheduler can pause between fibers — return to event loop, render frame, then resume.
- When the whole tree is reconciled, commit phase runs synchronously:
- Apply mutations.
- Run useLayoutEffect.
- Schedule useEffect.
Diff rules
- Same type + same key: reuse fiber, update props.
- Different type: unmount old subtree, mount new.
- Same type, different key in lists: reorder.
Keys must be stable; index keys cause re-render fan-out on reorder.
Why this improves perf
- Interruptible: long renders don't block the main thread; urgent input (typing) gets a render slice in between.
- Prioritization: different update sources (user input, transitions, idle) get different priorities.
startTransitionis "non-urgent." - Abandonment: a render in progress can be discarded if state changes mid-render.
- Selective hydration: in SSR, React hydrates components the user interacts with first.
Where Fiber is invisible
In typical app code you don't touch fibers. The visible API is hooks + transitions + Suspense, which the scheduler uses internally.
Common confusions
- Fiber ≠ Concurrent Mode. Fiber is the data structure (React 16+). Concurrent rendering is the feature set (React 18+) built on top.
useStatedoesn't always cause a re-render — if the new value isObject.isequal to current, React bails.- Strict Mode double-invokes to expose effect cleanup bugs caused by concurrent re-runs.
Performance considerations
- Fiber makes large trees survive concurrent rendering, not "faster."
- Reconciliation is still O(subtree size) per update. Memo + keys keep work scoped.
- Commit phase mutations are still synchronous; minimize what changes per render.
Interview framing
"Fiber is React's unit of work — each component instance is a Fiber node with state, hooks linked list, and tree pointers. Reconciliation walks the fiber tree producing a 'work-in-progress' version, diffing against the 'current' tree. Crucially, this walk is interruptible: the scheduler can pause between fibers, let urgent input through, then resume. That's what enables concurrent rendering: startTransition marks updates as non-urgent so they can be paused; selective hydration prioritizes user-interacted components. Pre-Fiber, the stack reconciler ran the whole tree synchronously and blocked the main thread. Fiber doesn't make rendering 'faster' in raw throughput — it makes rendering interruptible, which is what keeps UIs responsive under load."
Follow-up questions
- •What does interruptible mean for performance?
- •Why is keys stability critical?
- •How does selective hydration work?
Common mistakes
- •Confusing Fiber with Concurrent Mode.
- •Index keys breaking reconciliation.
- •Side-effects in render breaking the scheduler model.
Performance considerations
- •Throughput unchanged; responsiveness improved. Memo + keys keep work scoped.
Edge cases
- •Throwing in render (suspend / error).
- •useSyncExternalStore for external stores.
- •Reentrancy during commit.
Real-world examples
- •Lin Clark's React Conf 2017 talk, Andrew Clark's tweets, the React source.