What is Suspense?
Suspense lets a component "suspend" rendering while it’s waiting for something — like code still downloading, or data still loading — and shows a fallback UI in the meantime, without you needing to manually track a loading boolean.
Basic Suspense Usage
import { Suspense } from "react";
function App() {
return (
<Suspense fallback={<p>Loading...</p>}>
<ProfilePage />
</Suspense>
);
}React.lazy: Loading Components on Demand
React.lazy(() => import(...)) defers loading a component’s code until it’s actually needed, splitting it into a separate chunk. It must be rendered inside a Suspense boundary, which shows the fallback while the chunk downloads.
Lazy Loading a Component
import { lazy, Suspense } from "react";
const Chart = lazy(() => import("./Chart"));
function Dashboard() {
return (
<Suspense fallback={<p>Loading chart...</p>}>
<Chart />
</Suspense>
);
}
// Chart's code only downloads when Dashboard actually renders itMultiple Suspense Boundaries
Different parts of a page can suspend independently by wrapping them in separate Suspense boundaries — one slow section shows its own fallback while the rest of the page renders normally.
Independent Suspense Boundaries
function Dashboard() {
return (
<div>
<Header /> {/* renders immediately */}
<Suspense fallback={<Spinner />}>
<SlowWidget /> {/* only this section shows a fallback while loading */}
</Suspense>
<Footer /> {/* also renders immediately */}
</div>
);
}Suspense for Data Fetching
Beyond lazy-loaded components, Suspense also integrates with data-fetching libraries (like React Query or frameworks with built-in Suspense support) and the use() hook, letting a component suspend while data is still loading rather than manually rendering a loading state.
Suspense Doesn’t Catch Errors
Suspense only handles the "still loading" case. If the lazy import or data fetch actually fails, that’s a job for an error boundary — the two are commonly used together, wrapping Suspense inside an ErrorBoundary.
Best Practice
Use React.lazy for genuinely large, rarely-needed parts of the UI — a settings modal, a chart library, a rich text editor — not for every small component, where the extra network request outweighs any benefit.