Summary
Unnecessary re-renders, blocking updates, and oversized DOM trees are the three main causes of sluggish React UIs. React.memo, useMemo, and useCallback let you skip work; useTransition and useDeferredValue keep input responsive while slow updates run in the background; TanStack Virtual's useVirtualizer renders only visible rows.
Jump to the interview angleWhere render cost comes from
- Too many components re-render on a single interaction.
- A long task blocks the main thread past the 200ms INP budget.
- A large list renders every row at once instead of only the visible ones.
useTransition — keep input responsive
Mark the expensive state update as a transition. The input stays responsive while the heavy list re-renders in the background, and React interrupts that work if the user types again.
"use client";
import { useState, useTransition } from "react";
export function Filter({ rows }: { rows: string[] }) {
const [query, setQuery] = useState("");
const [shown, setShown] = useState(rows);
const [isPending, startTransition] = useTransition();
function onChange(e: React.ChangeEvent<HTMLInputElement>) {
const q = e.target.value;
setQuery(q); // urgent: keeps the input responsive
startTransition(() => {
// non-urgent: re-filter 10,000 rows without blocking keystrokes
setShown(rows.filter((r) => r.includes(q)));
});
}
return (
<>
<input value={query} onChange={onChange} />
<List rows={shown} dim={isPending} />
</>
);
}startTransition flags the setShown update as non-urgent, so typing never stutters. isPending drives a subtle dimmed state instead of a blocking spinner.
Profile before you memoize
Measure with the React DevTools Profiler first. Don't scatter useMemo/useCallback by reflex — the React Compiler (1.0, October 2025) auto-inserts memoization for Rules-of-React-compliant code.
Tradeoffs
Pros
- useTransition / useDeferredValue keep interactions responsive under heavy updates.
- Virtualization renders only visible rows — near-constant cost at any list size.
- The React Compiler removes most manual memoization.
Cons
- Over-memoization adds equality-check cost and clutter.
- Virtualization complicates focus, scroll restoration, and accessibility.
- Concurrent features surprise code that assumes synchronous renders.
Interview angle
Interviewers probe which tool fits which problem. Distinguish memoization (skip the render), transitions (defer the render), and virtualization (shrink the DOM). Name INP as the metric transitions target.
Soundbite: "Profile first — most renders are cheap. For slow ones: memo to skip, useTransition to defer, virtual to shrink the DOM."
Key terms
- useTransition
- Hook that marks a state update as interruptible so urgent events (typing) run first.
- useDeferredValue
- Hook that exposes a lagging value; background re-render is restartable on new input.
- useVirtualizer
- TanStack Virtual hook that renders only visible list items, keeping DOM size constant.
- INP
- Interaction to Next Paint — Core Web Vital measuring input-to-visual-update latency, budget 200 ms.
- React Compiler
- Build-time tool (stable v1.0, Oct 2025) that auto-inserts memoization for compliant code.