Concurrent Rendering allows React to interrupt rendering work and prioritize more urgent updates, helping keep the UI responsive during expensive renders.
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.
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:
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.
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 useTransitionuseDeferredValueThese features help React prioritize work and coordinate when UI becomes visible.
Consider a search page with an input and a list of 1,000 results.
Without prioritization, expensive rendering triggered by each keystroke can make the input feel sluggish.
useDeferredValueimport { useDeferredValue, useState } from "react";function App() {const [text, setText] = useState("");const deferredText = useDeferredValue(text);return (<><inputvalue={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.For a real performance improvement, combine deferred rendering with efficient list rendering, component memoization where appropriate, or virtualization for very large lists.