DevAcademy
LearnReactSuspense & Lazy Loading
AdvancedReact

Suspense & Lazy Loading

Learn how Suspense lets components "wait" for something before rendering, and how to lazily load components with React.lazy.

Reading Time

16 min

Lesson

Lesson 36 of 42

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 it

Multiple 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.

Interview Questions

Quick Quiz

1. What does the fallback prop on <Suspense> render?

2. What must a component created with React.lazy be rendered inside of?

3. Does Suspense handle errors, like a failed lazy import?