Advanced
Suspense, lazy & concurrent UI
Declarative loading states, code splitting, and useTransition.
Suspense lets a component "wait" for something (lazy code, data) and declaratively show a fallback while it loads, replacing scattered isLoading flags with a boundary.
Suspense is a restaurant buzzer for the UI: the section shows a placeholder table until the order (code or data) is ready, without freezing the whole restaurant.
Key concepts
1
React.lazy + Suspense code-splits components so they download on demand. With a Suspense-enabled data layer (Relay, React Query’s suspense mode, or a framework loader), data fetching participates in the same boundary.
`React.lazy`React.lazy
2
Concurrent features build on this: useTransition marks non-urgent updates so typing stays responsive while a heavy list re-renders in the background, and useDeferredValue defers expensive derived UI.
Concurrent featuresuseTransitionuseDeferredValue
3
Pitfall: triggering a fetch during render without a Suspense-aware source causes waterfalls; co-locate and parallelise. Interview angle: "how does Suspense improve perceived performance?" — declarative fallbacks + concurrent rendering keep input responsive.
Pitfall:Interview angle:
jsx
const Dashboard = React.lazy(() => import('./Dashboard'));
function App() {
const [isPending, startTransition] = useTransition();
return (
<Suspense fallback={<Spinner />}>
<Dashboard />
</Suspense>
);
}