DEV Community

Cover image for 🧡 Demystifying React Fiber: How Rendering Really Works
Vishwark
Vishwark

Posted on

🧡 Demystifying React Fiber: How Rendering Really Works

React Fiber is the core of modern React β€” but it often feels mysterious.

  • Why does React re-render only part of the UI?
  • How are Fiber nodes built?
  • Are HTML tags Fiber nodes?
  • What actually happens in the Render and Commit phases?

Let’s break everything down with simple explanations and intuitive examples.


🎯 What is React Fiber?

React Fiber is the internal rendering engine introduced in React 16.
It replaced the old synchronous renderer with a smarter system that supports:

  • Incremental rendering
  • Interruptible work
  • Scheduling & task prioritization
  • Concurrent rendering (React 18)
  • Recoverable rendering (can pause/resume/discard)

Fiber is essentially React’s virtual CPU that processes rendering in small chunks rather than one big blocking task.


🧠 Why Fiber Exists (The Problem)

Before Fiber, React used a call stack–based renderer:

❌ Cannot pause work
❌ Cannot prioritize urgent updates
❌ Cannot split rendering into units
❌ Long render blocks everything (typing, scrolling, clicking)

Fiber solves all these by representing each component as a small β€œwork unit” that React can schedule flexibly.


🧱 Every Component Becomes a Fiber Node

Every JSX element you write generates a Fiber node.

βœ” Component β†’ Fiber

βœ” DOM element β†’ Host Fiber

βœ” Text β†’ Text Fiber

Example:

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <button>Click</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Fiber tree:

App (FunctionComponent)
 └── div (HostComponent)
       β”œβ”€β”€ h1 (HostComponent)
       β”œβ”€β”€ #text "Hello" (HostText)
       └── button (HostComponent)
              └── #text "Click" (HostText)
Enter fullscreen mode Exit fullscreen mode

Yes β€” every HTML tag is considered a Host Element.


🌳 How the Fiber Tree Is Structured

Each Fiber node is connected using lightweight pointers:

  • child β†’ first child
  • sibling β†’ next node on the same level
  • return β†’ parent

Example visual:

AppFiber
  child β†’ divFiber

divFiber
  child β†’ h1Fiber
  sibling β†’ null

h1Fiber
  sibling β†’ textFiber

textFiber
  sibling β†’ buttonFiber

buttonFiber
  child β†’ textFiber(child)
Enter fullscreen mode Exit fullscreen mode

This avoids deep recursion and gives React full control over scheduling.


🌲 Current Fiber Tree vs Work-In-Progress Tree

React maintains two trees:

🟩 1. Current Tree (what’s on screen)

🟦 2. Work-In-Progress Tree (being prepared)

When React finishes preparing the WIP tree, it swaps it with the current tree in a single atomic commit.

This is how React ensures DOM updates appear consistent.


⚑ Does a State Update Re-render the Entire App?

❌ NO β€” it does not.

When you update state inside a component, React:

βœ” Starts reconciliation from that component’s Fiber node

βœ” Rebuilds only its subtree

βœ” Affects neither siblings nor parents (unless needed)

Example:

Root
 β”œβ”€β”€ Header
 β”œβ”€β”€ Sidebar
 β”œβ”€β”€ Dashboard
 β”‚     β”œβ”€β”€ Chart
 β”‚     β”œβ”€β”€ Filters
 β”‚     β”‚      └── SearchInput  <-- state updates here
 β”‚     └── Table
 └── Footer
Enter fullscreen mode Exit fullscreen mode

Only the SearchInput subtree (maybe 5–10 nodes) re-renders.

The 900+ other nodes remain untouched.

This is why React scales.


πŸ”Ό Why React Walks Upward First

When a state update happens, React:

  1. Marks the component’s Fiber as β€œdirty”
  2. Walks upward using .return pointers to find:
  • the nearest update root (usually the component itself)
  • the lane/priority context
    1. Then walks down and reconciles only the subtree

This upward walk does not re-render parents β€” it just gathers context.


🎬 The Two Phases of React Fiber

React’s lifecycle is divided into:


🟦 1. Render Phase (Reconciliation)

This is the phase where React determines what to render.

βœ” Can be paused

βœ” Can be interrupted

βœ” Can be restarted

βœ” Does NOT touch the DOM

βœ” Its basically asynchronous

This is where React:

  • Re-runs components
  • Rebuilds the work-in-progress Fiber tree
  • Compares new elements with old fibers
  • Decides which DOM nodes need updating
  • Computes effect list (what needs to change)

πŸ” How React walks in Render Phase

React uses a depth-first traversal of the Fiber tree:

beginWork β†’ child β†’ sibling β†’ parent β†’ next sibling…
Enter fullscreen mode Exit fullscreen mode

If React detects a higher-priority update (like user typing):

🚨 It can stop immediately
🟦 Save work
🟦 Resume later
🟦 Or discard the WIP tree

Example during typing:

  • User types "H"
  • React starts reconciliation of a long list
  • User types "He"

React cancels the low-priority reconciliation and starts fresh with latest input.

This is the power of Fiber.


🟩 2. Commit Phase

This is where React applies changes to the real DOM.

βœ” ALWAYS synchronous

βœ” CANNOT be interrupted

βœ” Must finish completely

βœ” Runs very fast

Commit phase steps:

1️⃣ Before Mutation Phase

React runs:

  • getSnapshotBeforeUpdate
  • Pre-mutation layout preparations

Purpose: Measure DOM before any changes occur.


2️⃣ Mutation Phase

React:

  • Inserts DOM nodes
  • Removes nodes
  • Updates props and attributes
  • Applies className and styles
  • Sets event listeners

This is the actual DOM manipulation step.


3️⃣ Layout Phase

React runs:

  • useLayoutEffect
  • Callback refs

Then the browser:

  • Paints the updated UI

Finally React schedules:

  • useEffect (runs asynchronously after paint)

πŸ†š Render Phase vs Commit Phase (Simple Analogy)

Render Phase = Planning

React decides what should change.

Commit Phase = Doing

React updates the DOM.


πŸ”₯ Putting It All Together

Let’s simulate a text input render:

User types a letter
↓
React schedules update on SearchInputFiber
↓
Render Phase:
    - Re-run SearchInput
    - Rebuild its subtree
    - Compute what changed (maybe text node)
↓
Commit Phase:
    - Update input DOM value
↓
Browser paints
Enter fullscreen mode Exit fullscreen mode

Only that tiny subtree is touched β€” the rest of your app sleeps peacefully. πŸ˜„


πŸŽ‰ Summary

  • Fiber allows React to pause, resume, and restart rendering.
  • Every element (component, DOM tag, text) becomes a Fiber node.
  • React keeps two Fiber trees: current + work-in-progress.
  • State updates do not re-render the entire tree β€” only the affected subtree.
  • Render Phase is interruptible; Commit Phase is not.
  • Fiber is the backbone of concurrent rendering, transitions, and scheduling.

React Fiber is elegant, powerful, and optimized for responsiveness β€” exactly what modern UIs need.


Top comments (0)