How React’s Runtime Optimizations Evolved from 15 to 18 – A Deep Technical Dive

This article walks through the evolution of React’s runtime architecture from version 15 to 18, explaining key concepts such as Fiber, Scheduler, priority lanes, concurrent mode, and new APIs like startTransition and useDeferredValue, while providing concrete code examples and visual diagrams.

ByteFE
ByteFE
ByteFE
How React’s Runtime Optimizations Evolved from 15 to 18 – A Deep Technical Dive

Design Strategies of Major JS Frameworks

React follows a runtime‑centric approach: when data changes it creates a new virtual DOM, computes the minimal set of changes with a diff algorithm, and applies them during runtime. In contrast, Svelte compiles templates ahead of time into native DOM operations, while Vue balances both by keeping a virtual DOM but performing many optimizations during compilation.

Framework design comparison
Framework design comparison

What Is Compile‑Time Optimization?

Vue’s template syntax (e.g., v‑if, v‑for) is limited and enumerable, allowing the compiler to pre‑compute many static aspects and generate more efficient code. Vue 3.0’s compiler can skip diffing static nodes, reducing unnecessary tree traversals.

Compile‑time optimization
Compile‑time optimization

Runtime Focus in React

React’s early versions (15) performed recursive, synchronous updates. The setState calls were synchronous, but React batched them to reduce renders. However, deep trees could exceed the 16.6 ms frame budget, causing jank.

class Example extends React.Component {
  constructor() {
    super();
    this.state = { val: 0 };
  }
  componentDidMount() {
    this.setState({ val: this.state.val + 1 });
    console.log(this.state.val);
    this.setState({ val: this.state.val + 1 });
    console.log(this.state.val);
    setTimeout(() => {
      this.setState({ val: this.state.val + 1 });
      console.log(this.state.val);
      this.setState({ val: this.state.val + 1 });
      console.log(this.state.val);
    }, 0);
  }
  render() { return null; }
}

In React 15 the printed order was 0,0,2,3, showing that setState is synchronous but its updates are batched.

Key Functions

_processPendingState

merges pending state queues into a single state object. batchedUpdates wraps a function to batch state updates; it is synchronous, so it cannot batch asynchronous callbacks.

React 16 – Introducing Fiber and Concurrent Mode

React 16 added a Scheduler, a new Reconciler based on the Fiber data structure, and the concept of Concurrent Mode, which makes rendering interruptible and priority‑aware.

Fiber architecture
Fiber architecture

Fiber Node Example

function FiberNode(tag, pendingProps, key, mode) {
  this.tag = tag;
  this.key = key;
  this.elementType = null;
  this.type = null;
  this.stateNode = null;
  this.return = null;
  this.child = null;
  this.sibling = null;
  this.index = 0;
  this.ref = null;
  this.pendingProps = pendingProps;
  this.memoizedProps = null;
  this.updateQueue = null;
  this.memoizedState = null;
  this.dependencies = null;
  this.mode = mode;
  this.effectTag = NoEffect;
  this.nextEffect = null;
  this.firstEffect = null;
  this.lastEffect = null;
  this.lanes = NoLanes;
  this.childLanes = NoLanes;
  this.alternate = null;
}

React now maintains two Fiber trees (current and work‑in‑progress) and switches pointers when an update is committed, enabling interruption.

Scheduler and Priority

The Scheduler stores ready tasks in a min‑heap ordered by expiration time. Priority levels include Immediate, UserBlocking, Normal, Low, and Idle. The Scheduler picks the task with the smallest expiration time (highest priority) and runs it until shouldYield() indicates the frame time is exhausted.

function workLoopConcurrent() {
  while (workInProgress !== null && !shouldYield()) {
    performUnitOfWork(workInProgress);
  }
}

When a task exceeds the frame budget, the Scheduler yields control back to the browser, allowing layout and paint to happen before resuming.

React 17 – Stabilizing Concurrent Mode and Multi‑Version Coexistence

React 17 moved event delegation from the document level to the root container, allowing multiple React versions to coexist on the same page without event conflicts.

Multi‑version event handling
Multi‑version event handling

The version also introduced the Lanes system, replacing the older expirationTime with bit‑field lanes for finer‑grained priority handling.

React 18 – Flexible Concurrent Rendering

React 18 ships with the new createRoot API that enables concurrent rendering by default. It also adds several developer‑friendly APIs:

startTransition – marks state updates as low‑priority transitions.

useTransition – provides an isPending flag to show loading UI.

useDeferredValue – defers rendering of a value until the browser is idle.

SSR now supports <Suspense> with fallback streaming.

startTransition Example

import { startTransition } from 'react';
// Urgent update – show typed text immediately
setInputValue(input);
// Transition – low‑priority update
startTransition(() => {
  setSearchQuery(input);
});

Updates inside startTransition can be interrupted by higher‑priority events, preventing UI jank.

useDeferredValue Example

const [deferredText] = useDeferredValue(text, { timeoutMs: 2000 });

The deferred value is rendered with lower priority, automatically falling back to the immediate value if the render is fast.

SSR Suspense Support

When rendering on the server, React streams the fallback UI first and replaces it with the actual component once it resolves, enabling progressive hydration.

<Layout>
  <Article />
  <Suspense fallback={<Spinner />}>
    <Comments />
  </Suspense>
</Layout>

Conclusion and Further Reading

Reading the React source code directly can be daunting. It is recommended to first study high‑level architecture overviews (e.g., the “React Technical Deep Dive” and “Illustrated React Source” series) before diving into specific modules such as Fiber, Scheduler, or Concurrent Mode.

React Technical Deep Dive: https://react.iamkasong.com/

Illustrated React Source: https://github.com/7kms/react-illustration-series

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ReactSchedulerFiberConcurrent ModeReact 18Runtime Optimization
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.