Subroutine Logo
Subroutine
← Back to Articles Languages Advanced 5 min read

React Virtual DOM, Fiber Architecture & Concurrent Rendering

Under the hood of React's doubly linked-list Fiber reconciler, double buffering, and main-thread time-slicing.

Published: 2026-08-09
#React#JavaScript#TypeScript#Frontend#Web Performance

Prior to React 16, React used a synchronous recursive tree traversal engine known as the Stack Reconciler.

When a high-level state change occurred in a complex app, the Stack Reconciler recursively walked the entire Virtual DOM tree in a single continuous synchronous execution block. If tree diffing took more than 16.6ms16.6\text{ms} (the duration of a single 60Hz frame), the browser’s main UI thread froze - causing dropped frames, sluggish text input, and un-responsive UI animations.

React 16 introduced the Fiber Reconciler, completely re-architecting React’s internals around a custom cooperatively scheduled linked-list data structure.


1. Summary & Key Takeaways

  • Linked List Pointers: child, sibling, and return replace the native call stack, allowing React to pause and resume work.
  • Double Buffering: current vs workInProgress trees compute updates offscreen before flushing to the real DOM.
  • Two-Phase Commit: Asynchronous, interruptible Render Phase followed by a synchronous, atomic Commit Phase.

2. Interactive Fiber Reconciler Simulator

Test how React builds workInProgress Fiber trees offscreen and applies atomic DOM updates:

React Fiber Architecture & Reconciliation

Linked-List Work Tree: `child`, `sibling`, `return` Double-Buffering

Reconciler Phase:Idle
Frame Budget: 16.6ms (60 FPS Time-Slicing Scheduler)
Fiber Linked-List Structure (workInProgress Tree)Pointer Connections: child | sibling | return
<App />HostRoot
child ➔ <Header />
<Header />Pure Component
sibling ➔ <CounterButton />
<CounterButton />count: 0
effectTag:NONE
React Fiber Engine Idle: Double-buffering current vs workInProgress trees.

3. React Reconciliation Phase Pipeline

graph TD
    subgraph Phase1["1. Render Phase (Async & Interruptible)"]
    STATE["setState() Triggered"] --> WIP["Create workInProgress Tree"]
    WIP --> DIFF["Perform Virtual DOM Diffing"]
    DIFF --> FLAGS["Assign Effect Flags: Placement, Update, Deletion"]
    end

    subgraph Phase2["2. Commit Phase (Synchronous & Atomic)"]
    FLAGS --> FLUSH["Flip Pointer: root.current = workInProgress"]
    FLUSH --> DOM["Mutate Real Browser DOM"]
    DOM --> HOOKS["Trigger useLayoutEffect & useEffect"]
    end

4. Multi-Language Fiber Internals Implementation

React Fiber Architecture Implementation
react_fiber_node.ts
TypeScript (Fiber Node)
// React Fiber Node Type Definition
export type WorkTag = 0 | 3 | 5; // FunctionComponent, HostRoot, HostComponent

export interface Fiber {
  // Identity & Type
  tag: WorkTag;
  type: any;                 // 'div', 'button', or Component Function
  stateNode: any;            // Reference to actual DOM Node

  // Doubly Linked-List Tree Pointers
  child: Fiber | null;       // Points to FIRST child node
  sibling: Fiber | null;     // Points to NEXT sibling node
  return: Fiber | null;      // Points UP to parent node

  // Double Buffering & State
  alternate: Fiber | null;   // Mirror node in current <-> workInProgress tree
  memoizedState: any;        // Linked-list of hooks (useState, useEffect)
  flags: number;             // Mutation flags: Placement (2), Update (4), Deletion (8)
}

5. Engineering Guidance

  1. Fiber Time-Slicing: Breaks render work into 5ms micro-tasks so input typing stays responsive during heavy re-renders.
  2. Concurrent Features: useTransition and useDeferredValue leverage Fiber interrupts to defer expensive offscreen UI trees.