frontend / react / react_fiber.md

React Fiber

4 interview angles 7 min read source

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:

// 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.