Feel React's concurrent rendering. Type into a filter over a deliberately heavy list: in blocking mode the input janks while the big render runs; useDeferredValue and useTransition keep typing instant and update the list at a lower priority. Same list, same filter — different scheduling.
▶ Live demo · The difference · Run locally
"Concurrent rendering keeps the UI responsive" is hard to appreciate until you feel a laggy input become smooth. This filters a genuinely heavy list (~1,200 costly rows) so blocking mode really does jank — and a live main-thread heartbeat freezes to prove it — then the concurrent hooks make it buttery.
Three modes over the identical filter + list:
- blocking (useState) — the filter runs synchronously on every keystroke. Rendering the heavy rows blocks the main thread, so the input itself stutters and the heartbeat dot freezes (watch the "worst frame gap" climb).
- useDeferredValue — the input binds to the live value (instant); the list reads a deferred copy that lags at lower priority. While it catches up, the old list is shown dimmed.
- useTransition — the keystroke updates the input immediately, and the filter update is wrapped in
startTransition, so React renders the list at low priority and gives you anisPendingflag. The input never blocks.
// useDeferredValue — defer a VALUE you already have
const deferred = useDeferredValue(text);
const list = useMemo(() => filter(deferred), [deferred]);
// useTransition — wrap the STATE UPDATE that causes the heavy work
const [isPending, startTransition] = useTransition();
onChange = (v) => { setText(v); startTransition(() => setQuery(v)); };Both tell React "this update is low-priority — keep the UI interactive and finish it when you can." Use useDeferredValue when you already have the value (e.g. a prop); use useTransition when you own the state update and want an isPending flag for a spinner.
npm install
npm run dev
npm run buildIdeas: a startTransition for route/tab switches, useDeferredValue with <Suspense>, an "interrupted render" visualization, comparison vs debouncing. PRs welcome.
If this made concurrent React click, a ⭐ helps others find it.
MIT © dev48v