Frontend / React / react_fiber.md

React Fiber

Updated 4 interview angles 7 min read source
On this page9
  1. Table of Contents
  2. What is React Fiber?
  3. Fiber Architecture
  4. Key Features
  5. Work Loop
  6. Benefits
  7. Common Interview Questions
  8. Summary
  9. Interview angle

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

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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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:

javascript
// 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 4

  • “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.