You've probably heard about React Fiber.
But why does it matter?
And more importantly:
What problem was Fiber actually designed to solve?
Fiber is React's internal architecture for representing and processing the work needed to update the UI.
You don't normally interact with Fiber directly, but understanding the idea behind it gives you a much better mental model of how modern React rendering works.
A useful simplified mental model is:
Component Tree
↓
Fiber Tree
↓
Scheduled Work
↓
Render / Reconciliation
↓
Commit
↓
Updated UI
The important part isn't memorizing React's internal Fiber fields.
It's understanding why this architecture exists.
🧠 Why Did React Need Fiber?
Imagine a React application with a large component tree.
A state update happens:
State Update
↓
React needs to render
↓
Large component tree
↓
A lot of JavaScript work
Rendering isn't free.
React may need to evaluate components, compare the new result with the previous one, determine what changed, and eventually apply the required updates.
If a large amount of work has to happen as one uninterrupted operation, it can keep the browser's main thread busy.
And the main thread isn't only responsible for React.
It also needs to handle things like:
- User interactions
- JavaScript execution
- Layout
- Painting
- Animations
- Browser events
So the problem becomes:
How can React manage rendering work without allowing expensive updates to unnecessarily block more important work?
This is where Fiber becomes important.
⚙️ Fiber as a Unit of Work
One of the important ideas behind Fiber is that React can represent rendering work as smaller units rather than treating an entire update as one indivisible operation.
Conceptually:
Large Rendering Task
↓
┌───────────────────────┐
│ Work A │
│ Work B │
│ Work C │
│ Work D │
│ Work E │
└───────────────────────┘
Instead of thinking only in terms of:
"Render the entire application"
React can reason about individual pieces of work.
That gives React more flexibility when deciding how and when that work should be processed.
This is one of the architectural ideas that enables React to support more sophisticated scheduling and concurrent rendering capabilities.
🌳 Component Tree vs Fiber Tree
As developers, we usually think about our application as a component tree:
App
├── Header
├── Sidebar
├── Dashboard
│ ├── Statistics
│ ├── Chart
│ └── ProductList
│ ├── ProductCard
│ ├── ProductCard
│ └── ProductCard
└── Footer
Internally, React maintains a corresponding structure involving Fiber nodes.
A simplified mental model is:
Your Components
↓
React's Fiber representation
↓
Units of rendering work
A Fiber node contains information React needs while processing a particular part of the tree.
As frontend developers, we normally don't need to interact with these nodes directly.
They're an implementation detail.
But understanding that this internal representation exists helps explain how React can perform reconciliation and manage rendering work.
🔄 Render Phase vs Commit Phase
Another important concept is that React's work can be understood through two major phases:
Update
↓
Render Phase
↓
Commit Phase
These phases have different responsibilities.
Render Phase
During the render phase, React determines what the next UI should look like.
Conceptually:
State / Props Change
↓
Component Rendering
↓
Reconciliation
↓
Determine what changed
React is essentially trying to answer:
"Given the new state and props, what should the UI look like?"
This is where React performs much of the computational work involved in rendering and reconciliation.
Importantly, rendering does not mean React has already changed the DOM.
It's primarily about figuring out the next result.
Commit Phase
Once React has finished determining the required changes, it can move to the commit phase.
Finished Render Work
↓
Commit
↓
Apply Required Changes
↓
DOM
The commit phase is where React applies the necessary changes to the host environment, such as the browser DOM.
This distinction is useful when thinking about React performance because expensive rendering work and the actual DOM mutations are not the same thing.
🚦 Scheduling and Prioritization
One of the most interesting ideas behind modern React is that not all updates necessarily have the same urgency.
Consider two updates:
User clicks a button
↓
Should feel responsive immediately
versus:
Large list needs to update
↓
Can potentially happen with lower urgency
A useful conceptual model is:
React Work
│
┌───────────┴───────────┐
↓ ↓
More urgent Less urgent
│ │
↓ ↓
User interaction Background UI work
This ability to reason about work and prioritize it is an important part of the architecture behind React's concurrent features.
It's worth being precise here:
Concurrent rendering does not mean React is rendering everything on multiple threads.
JavaScript in the browser still primarily runs on the main thread.
The important idea is that React has more flexibility around when rendering work is performed, interrupted, resumed, or abandoned before committing the final result.
🧩 Why This Matters for Performance
Understanding Fiber changes how you think about React performance.
It's easy to think:
"React is fast because it uses a Virtual DOM."
That's an oversimplification.
Modern React performance involves several different concepts:
State Updates
↓
Scheduling
↓
Rendering
↓
Reconciliation
↓
Commit
↓
Browser Rendering
Each stage can contribute to the overall cost of an interaction.
For example, imagine a product page rendering 2,000 product cards.
2,000 Products
↓
2,000 ProductCard components
↓
Large amount of rendering work
↓
Slower interaction
A developer might immediately think:
"I should add
React.memo."
But profiling might reveal a more fundamental problem:
Why are we rendering 2,000 products in the first place?
If the user can only see 20 products at a time, reducing the number of rendered components can be much more effective than trying to make every individual component slightly faster.
That leads to an important performance principle:
Before optimizing individual units of work, ask whether you can reduce the amount of work altogether.
🔍 Fiber and React Profiler
This is also why tools such as the React Profiler are useful.
Instead of guessing:
"Maybe useMemo will fix it."
"Maybe React.memo will fix it."
"Maybe useCallback will fix it."
you can first ask:
What work is actually happening during this interaction?
For example, you might see something like:
ProductGrid 79.9ms
ProductCard 0.4ms
ProductCard 0.3ms
ProductCard 0.4ms
...
At first glance, you might think: "ProductGrid is slow", But if thousands of ProductCards are being processed underneath it, the real problem may be the quantity of work, rather than one particularly slow component.
After reducing the visible list:
ProductGrid 1.2ms
ProductCard 0.2ms
ProductGridHeader 0.1ms
Now the performance characteristics are completely different.
This is a good example of why performance optimization should usually follow this process:
Measure
↓
Identify the expensive work
↓
Understand why it happens
↓
Reduce unnecessary work
↓
Optimize what remains
↓
Measure again
🎯 The Important Takeaway
I don't think frontend developers need to memorize every Fiber field or understand every internal implementation detail.
The valuable part is understanding the reason Fiber exists.
Rendering UI can be expensive, so React needs an architecture that allows it to:
- Represent rendering work
- Break work into manageable units
- Schedule work
- Prioritize updates
- Reconcile changes
- Commit the final result
Instead of immediately asking:
"Which optimization should I use?"
I think a better first question is:
"What work is React doing, why is it doing that work, and can I reduce it?"
Understanding Fiber gives us a much stronger mental model for reasoning about all of those decisions.
Top comments (0)