React Fiber and the DOM: Understanding the Real Tree
The Spark
I was watching Dan Abramov's talk "React for Two Computers", and right at the start he makes a simple but powerful analogy: a scriptwriter writes instructions, and the actor performs them. The actor executes the lines, but the scriptwriter is the one keeping track of state, deciding what happens next, and orchestrating the performance.
It got me thinking about React in a new way. Maybe the Fiber tree is like the scriptwriter, and the DOM is the stage. Updates don't go straight to the DOM; Fiber could be deciding what should change and instructing the DOM how to reflect it. The DOM is the performance, but the mind behind it is something else entirely.
Virtual DOM vs Real DOM
React didn't start with Fiber, but it did start with the idea that the DOM is expensive to manipulate directly. Enter the virtual DOM: a lightweight representation of what the DOM should look like.
Every render produces a virtual DOM tree. React compares this tree to the previous one and calculates the minimal set of changes required — reconciliation — then updates the real DOM accordingly.
function App() {
const [count, setCount] = React.useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Clicked {count} times
</button>
);
}
Even though setCount triggers a new render, React patches only what changed.
Analogy: Think of the virtual DOM as a rehearsal script. The script shows what the stage should look like, letting React plan changes efficiently before telling the actors (DOM nodes) what to do.
Fiber: The Scriptwriter of React
Fiber generalizes the virtual DOM, making React incremental and interruptible. Updates are broken into small units, prioritized, and scheduled. Fiber can pause mid-render, resume later, or handle urgent updates first.
Analogy: Fiber is the scriptwriter keeping a detailed ledger of every character (component), their lines (state), and their relationships. The actors (DOM nodes) perform only when Fiber signals them.
Fiber Tree: DOM Tree:
App <body>
├─ Header ├─ #root
├─ Content ├─ header
│ └─ Article ├─ div.article
└─ Footer └─ footer
The trees can differ. Fiber cares about ownership, state, and relationships. The DOM cares about layout and rendering. Fiber can move, add, or remove elements in the DOM while maintaining its mental model of ownership.
Event Handling and Context: Following the Script
React's synthetic event system travels along the Fiber tree, not the DOM tree. Clicks, keyboard events, or context updates behave predictably even if elements move around in the DOM.
const ThemeContext = React.createContext('light');
function Parent() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
function Child() {
const theme = React.useContext(ThemeContext); // "dark"
return <div>{theme}</div>;
}
Even if Child were rendered elsewhere in the DOM, it still respects its Fiber parent's context. Ownership is maintained in the Fiber tree.
Why This Matters
Understanding Fiber vs DOM helps explain many "magical" React behaviors:
- Event bubbling: follows Fiber, not DOM
- State and context: preserved according to ownership, not placement
- Scheduling: updates can be interrupted or prioritized without breaking consistency
Analogy: The DOM is the stage; Fiber is the director. The actors perform, but the director decides timing, cues, and who should move where.
Takeaway: A Performance Well-Directed
Next time you inspect the DOM and wonder why React behaves the way it does, it can help to remember the scriptwriter analogy. Fiber is quietly orchestrating every line, cue, and move, while the DOM shows the final performance. Understanding this distinction can make debugging, reasoning about component behavior, and designing React apps far more intuitive.
And just like Shakespeare's actors who never see the full script, the audience (or in our case, the browser) only sees the performance. But behind the scenes, Fiber keeps the play running — and perhaps, as the Bard might say, all the world's a stage, and all the components merely players.