React Fiber
React Fiber is the new reconciliation engine in React 16+ that enables incremental rendering and better performance for complex applications.
Table of Contents
- React Fiber
What is React Fiber?
React Fiber is a complete rewrite of React’s reconciliation algorithm that enables incremental rendering, allowing React to split rendering work into chunks and prioritize updates.
Key Concepts:
- Incremental Rendering: Split work into chunks
- Priority Scheduling: Prioritize important updates
- Interruptible: Can pause and resume work
- Backward Compatible: Same API, better performance
Fiber Node Structure:
// Fiber node represents a unit of work
const fiberNode = {
// Tag identifying the type of work
tag: HostComponent, // div, span, etc.
// Key for reconciliation
key: null,
// Element type
elementType: 'div',
// DOM node (if any)
stateNode: divElement,
// Return, child, and sibling pointers
return: parentFiber,
child: firstChildFiber,
sibling: nextSiblingFiber,
// Work properties
pendingProps: { className: 'container' },
memoizedProps: { className: 'container' },
memoizedState: null,
// Effect flags
flags: NoFlags,
// Priority
lanes: NoLanes,
// Child lanes
childLanes: NoLanes
};
Fiber Architecture
1. Fiber Tree Structure:
// Fiber creates a tree of work units
function App() {
return (
<div>
<header>
<h1>Title</h1>
</header>
<main>
<p>Content</p>
</main>
</div>
);
}
// Fiber tree representation:
// App Fiber
// ├── div Fiber
// ├── header Fiber
// │ └── h1 Fiber
// └── main Fiber
// └── p Fiber
2. Work Unit Representation:
// Each React element becomes a Fiber node
function createFiberFromElement(element) {
return {
tag: getTagFromElement(element),
key: element.key,
elementType: element.type,
pendingProps: element.props,
memoizedProps: null,
memoizedState: null,
return: null,
child: null,
sibling: null,
flags: NoFlags,
lanes: NoLanes
};
}
// Example: <div className="container">Hello</div>
const fiber = {
tag: HostComponent,
elementType: 'div',
pendingProps: { className: 'container', children: 'Hello' }
};
3. Priority Levels:
// Fiber uses priority levels for scheduling
const PriorityLevels = {
ImmediatePriority: 1, // Sync updates
UserBlockingPriority: 2, // User interactions
NormalPriority: 3, // Regular updates
LowPriority: 4, // Background updates
IdlePriority: 5 // Idle time updates
};
// React assigns priorities based on update type
function scheduleUpdate(fiber, priority) {
fiber.lanes = priority;
scheduleWork(fiber);
}
Key Features
1. Incremental Rendering:
// Fiber can split work into chunks
function renderInChunks(fiber) {
const timeSlice = 5; // 5ms time slice
let startTime = performance.now();
while (fiber && performance.now() - startTime < timeSlice) {
// Process one fiber node
fiber = performUnitOfWork(fiber);
}
// If there's more work, schedule it for later
if (fiber) {
requestIdleCallback(() => renderInChunks(fiber));
}
}
// This allows React to:
// - Respond to user input during rendering
// - Prioritize important updates
// - Maintain smooth animations
2. Priority Scheduling:
// Different types of updates get different priorities
function handleUserClick() {
// High priority - user interaction
setState(newState, UserBlockingPriority);
}
function handleDataUpdate() {
// Normal priority - data update
setState(newState, NormalPriority);
}
function handleBackgroundTask() {
// Low priority - background work
setState(newState, LowPriority);
}
// React schedules work based on priority
function scheduleWork(fiber) {
if (fiber.lanes === UserBlockingPriority) {
// Schedule immediately
scheduleSyncWork(fiber);
} else {
// Schedule for later
scheduleAsyncWork(fiber);
}
}
3. Interruptible Work:
// Fiber can pause and resume work
function performUnitOfWork(fiber) {
// Check if we should yield control
if (shouldYield()) {
// Save current progress
return fiber; // Return to continue later
}
// Process this fiber
const nextFiber = beginWork(fiber);
if (nextFiber) {
return nextFiber;
}
// Complete this fiber
return completeUnitOfWork(fiber);
}
function shouldYield() {
// Check if there's higher priority work
// or if we've exceeded time slice
return hasHigherPriorityWork() || hasExceededTimeSlice();
}
Work Loop
1. Render Phase:
// Render phase is interruptible
function renderPhase(fiber) {
while (fiber && !shouldYield()) {
fiber = performUnitOfWork(fiber);
}
if (fiber) {
// More work to do, schedule continuation
scheduleCallback(renderPhase, fiber);
} else {
// Render complete, move to commit phase
commitRoot();
}
}
function performUnitOfWork(fiber) {
// Begin work on this fiber
const nextFiber = beginWork(fiber);
if (nextFiber) {
return nextFiber;
}
// Complete work on this fiber
return completeUnitOfWork(fiber);
}
2. Commit Phase:
// Commit phase is synchronous and uninterruptible
function commitRoot() {
// Apply all side effects
commitBeforeMutationEffects();
commitMutationEffects();
commitLayoutEffects();
}
function commitMutationEffects() {
// Apply DOM changes
// This is where the actual DOM updates happen
// Must be synchronous to maintain consistency
}
3. Work Scheduling:
// Fiber uses different scheduling strategies
function scheduleWork(fiber) {
const priority = fiber.lanes;
switch (priority) {
case ImmediatePriority:
// Sync work - execute immediately
performSyncWorkOnRoot(fiber);
break;
case UserBlockingPriority:
case NormalPriority:
case LowPriority:
// Async work - schedule for later
scheduleAsyncWork(fiber);
break;
default:
// Idle work - when browser is idle
scheduleIdleWork(fiber);
}
}
Benefits
1. Better Performance:
// Fiber enables better performance through:
// - Incremental rendering
// - Priority-based scheduling
// - Efficient work splitting
function ExpensiveComponent({ data }) {
// With Fiber, this expensive render can be:
// - Split into chunks
// - Interrupted for user input
// - Resumed later
return (
<div>
{data.map(item => (
<ExpensiveItem key={item.id} data={item} />
))}
</div>
);
}
2. Responsive UI:
// Fiber keeps UI responsive during updates
function App() {
const [count, setCount] = useState(0);
const [data, setData] = useState([]);
useEffect(() => {
// This heavy update won't block user interactions
fetchData().then(setData);
}, []);
return (
<div>
<button onClick={() => setCount(count + 1)}>
Count: {count} {/* Always responsive */}
</button>
<DataList data={data} /> {/* Can be rendered incrementally */}
</div>
);
}
3. Concurrent Features:
// Fiber enables concurrent features like:
// - Suspense for data fetching
// - Concurrent mode
// - Automatic batching
// Suspense with Fiber
function DataComponent() {
return (
<Suspense fallback={<Loading />}>
<AsyncData />
</Suspense>
);
}
// Concurrent mode
function ConcurrentApp() {
return (
<React.unstable_ConcurrentMode>
<App />
</React.unstable_ConcurrentMode>
);
}
4. Better Error Handling:
// Fiber provides better error boundaries
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// Fiber provides better error information
console.log('Error:', error);
console.log('Error Info:', errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Common Interview Questions
Q: What is React Fiber?
- React Fiber is the new reconciliation engine that enables incremental rendering and better performance.
Q: What are the main benefits of React Fiber?
- Incremental rendering, priority scheduling, interruptible work, and better performance for complex applications.
Q: How does Fiber improve performance?
- By splitting rendering work into chunks, prioritizing updates, and allowing work to be interrupted and resumed.
Q: What is the difference between render and commit phases?
- Render phase is interruptible and creates the work tree, commit phase is synchronous and applies changes to the DOM.
Q: How does Fiber handle priority scheduling?
- Different types of updates get different priority levels, and React schedules work based on these priorities.
Q: What is incremental rendering?
- The ability to split rendering work into small chunks that can be processed over time without blocking the main thread.
Q: How does Fiber maintain backward compatibility?
- Fiber maintains the same React API while improving the internal reconciliation algorithm.
Q: What are concurrent features enabled by Fiber?
- Suspense, concurrent mode, automatic batching, and better error handling.
Q: How does Fiber handle interruptions?
- Fiber can pause work when higher priority tasks arrive and resume work later.
Q: What is the work loop in Fiber?
- The process of performing work units, checking for interruptions, and scheduling continuation of work.
Summary
- React Fiber is the new reconciliation engine enabling incremental rendering
- Incremental rendering splits work into chunks for better performance
- Priority scheduling ensures important updates happen first
- Interruptible work allows React to respond to user input during rendering
- Render phase is interruptible, commit phase is synchronous
- Concurrent features like Suspense are built on top of Fiber
- Backward compatibility means existing React code works without changes
- Better performance for complex applications with many components
- Understanding Fiber is crucial for React performance optimization
Interview angle
- “What is Fiber?” - the reconciler rewritten in React 16 so rendering work can be split into units, paused, resumed, reprioritised and abandoned. The old stack reconciler recursed synchronously and could not be interrupted.
- “What does that unlock?” - concurrent features: transitions, Suspense, time slicing so a long render does not block input. Fiber is the enabling architecture, not a feature you use directly.
- “What are the two phases?” - render (build the work-in-progress tree, interruptible, no side effects - which is why render must be pure and may run twice) and commit (apply to the DOM, synchronous and uninterruptible).
- “Does Fiber make React faster?” - not raw throughput; it makes it more responsive by yielding to higher-priority work. Interruptibility is about latency, not total work.