Home
React
Performance: Concurrent Rendering
Daniel Nguyen
Daniel Nguyen
July 27, 2025
1 min

Concurrent Rendering allows React to interrupt rendering work and prioritize more urgent updates, helping keep the UI responsive during expensive renders.

1. The Problem: Expensive Rendering

Browsers aim for 60 FPS, giving each frame approximately 16.7 ms to render.

When JavaScript monopolizes the main thread for too long, users may experience input lag, delayed updates, and stuttering animations.

React rendering itself can contribute to this problem, especially when a component tree is expensive to render.

2. What Is Concurrent Rendering?

Concurrent Rendering is a rendering capability introduced in React 18 that lets React prepare UI updates without treating every render as one uninterrupted task.

React can:

  • Start rendering an update.
  • Pause or abandon render work when appropriate.
  • Prioritize more urgent updates.
  • Resume or restart work later.

This helps keep interactions responsive while React prepares less urgent UI changes.

Important: React can yield between units of its own rendering work, but it cannot interrupt a long-running synchronous JavaScript function in the middle of execution. Concurrent rendering also does not make expensive computations inherently faster.

3. What Changed in React 18?

Concurrent rendering is not a switch you enable directly. React 18 introduced a concurrent rendering foundation that powers APIs for coordinating updates.

Examples include:

  • startTransition and useTransition
  • useDeferredValue
  • Suspense-enabled rendering patterns
  • Streaming server-side rendering with Suspense

These features help React prioritize work and coordinate when UI becomes visible.

4. Why Prioritization Matters

Consider a search page with an input and a list of 1,000 results.

  • Typing in the input is urgent.
  • Updating an expensive result list can be deferred.

Without prioritization, expensive rendering triggered by each keystroke can make the input feel sluggish.

5. Example: useDeferredValue

import { useDeferredValue, useState } from "react";
function App() {
const [text, setText] = useState("");
const deferredText = useDeferredValue(text);
return (
<>
<input
value={text}
onChange={event => setText(event.target.value)}
placeholder="Search..."
/>
<SlowList text={deferredText} />
</>
);
}

Here, text updates immediately, while SlowList can continue rendering with the previous deferredText value until React can process the newer value.

React can prioritize the input update over the deferred list update, keeping typing responsive when the list is expensive to render.

Important details

  • useDeferredValue does not debounce input or reduce the number of computations by itself.
  • It does not guarantee that the list updates after a fixed delay.
  • React may interrupt and restart deferred rendering as newer values arrive.
  • The list must actually be expensive to render for the benefit to be noticeable.

For a real performance improvement, combine deferred rendering with efficient list rendering, component memoization where appropriate, or virtualization for very large lists.


Tags

#ReactPerformance

Share

Daniel Nguyen

Daniel Nguyen

Frontend Developer

Frontend developer specializing in React, Next.js, and JavaScript. Writing practical guides on modern web development at Dev98.

Expertise

React
Next.js
JavaScript
TypeScript
Python

Social Media

githublinkedinyoutubewebsite

Related Posts

React Performance
Performance: Windowing
August 06, 2025
1 min
Dev98

Dev98

React · Next.js · Web development