🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
REFERENCEreact

react Documentation

LOADING ENGINE...

Handling Loading with Suspense

AI & DATA SCIENCE // suspense

Suspense lets a component tree display a fallback UI while something inside it isn't ready yet, most commonly used for React.lazy()'s asynchronously-loaded components.

Syntax

<Suspense fallback={<Loading />}>
  <SomeComponent />
</Suspense>

Deep Dive Course

Suspense wraps part of the component tree and shows its fallback prop instead of that tree's actual content whenever something inside has suspended, signaled a not-ready-yet state, most classically a React.lazy()-loaded component whose code chunk is still downloading. Once the suspended work actually completes, Suspense automatically swaps the fallback out for the real content. A single Suspense boundary can wrap multiple lazy components at once, showing one shared fallback until all of them are ready, and multiple Suspense boundaries can also be nested to show more granular, localized loading states for different parts of a page independently.

1Understanding Handling Loading with Suspense

Suspense wraps part of the component tree and shows its fallback prop instead of that tree's actual content whenever something inside has suspended, signaled a not-ready-yet state, most classically a React.lazy()-loaded component whose code chunk is still downloading. Once the suspended work actually completes, Suspense automatically swaps the fallback out for the real content. A single Suspense boundary can wrap multiple lazy components at once, showing one shared fallback until all of them are ready, and multiple Suspense boundaries can also be nested to show more granular, localized loading states for different parts of a page independently.

💡

Wrap multiple related lazy components in one single shared Suspense boundary when they should all appear together at once, avoiding a jarring, staggered sequence of separate loading indicators popping in one after another as each component individually finishes loading.

editor.html
import React, { Suspense } from 'react';

const Chart = React.lazy(() => import('./Chart'));
const Table = React.lazy(() => import('./Table'));

function Dashboard() {
  return (
    <Suspense fallback={<p>Loading dashboard...</p>}>
      <Chart />
      <Table />
    </Suspense>
  );
}
localhost:3000

2Practical Example

Here is a real-world application of Handling Loading with Suspense showing how it is used in production React code.

editor.html
function Page() {
  return (
    <>
      <Suspense fallback={<p>Loading header...</p>}>
        <LazyHeader />
      </Suspense>
      <Suspense fallback={<p>Loading content...</p>}>
        <LazyContent />
      </Suspense>
    </>
  );
}
localhost:3000

3Best Practices

Follow these guidelines when working with Handling Loading with Suspense:

1. Wrap a group of related lazy components in one shared Suspense boundary when they logically belong together and should appear as a group, not staggered in one by one

2. Nest separate, more granular Suspense boundaries around independent sections of a page when you want each section's loading state to be independent of the others

3. Design a fallback UI, like a skeleton screen, that closely matches the actual content's eventual layout, minimizing visual jank when the real content finally replaces it

⚠️

Tip: Wrap multiple related lazy components in one single shared Suspense boundary when they should all appear together at once, avoiding a jarring, staggered sequence of separate loading indicators popping in one after another as each component individually finishes loading.

editor.html
import React, { Suspense } from 'react';

const Chart = React.lazy(() => import('./Chart'));
const Table = React.lazy(() => import('./Table'));

function Dashboard() {
  return (
    <Suspense fallback={<p>Loading dashboard...</p>}>
      <Chart />
      <Table />
    </Suspense>
  );
}
localhost:3000

Examples

Example 01Basic Usage
import React, { Suspense } from 'react';

const Chart = React.lazy(() => import('./Chart'));
const Table = React.lazy(() => import('./Table'));

function Dashboard() {
  return (
    <Suspense fallback={<p>Loading dashboard...</p>}>
      <Chart />
      <Table />
    </Suspense>
  );
}
Example 02Advanced Example
function Page() {
  return (
    <>
      <Suspense fallback={<p>Loading header...</p>}>
        <LazyHeader />
      </Suspense>
      <Suspense fallback={<p>Loading content...</p>}>
        <LazyContent />
      </Suspense>
    </>
  );
}

Best Practices

  • Wrap a group of related lazy components in one shared Suspense boundary when they logically belong together and should appear as a group, not staggered in one by one
  • Nest separate, more granular Suspense boundaries around independent sections of a page when you want each section's loading state to be independent of the others
  • Design a fallback UI, like a skeleton screen, that closely matches the actual content's eventual layout, minimizing visual jank when the real content finally replaces it

Interview Question

Why might wrapping several related lazy-loaded components in one single shared Suspense boundary be preferable to giving each one its own separate Suspense boundary?

Hint: Think about what the user actually sees on screen if several independently-loading pieces of a page finish downloading at noticeably different times.

If several related components, say a chart and its accompanying data table that are meant to be viewed together, each have their own separate Suspense boundary, they'll pop into view independently and potentially at quite different times depending on how quickly each one's code chunk happens to download, producing a jarring, staggered appearance where part of a logically unified section shows up well before the rest of it, which can look broken or incomplete even though nothing is actually wrong. Wrapping both components in one single shared Suspense boundary instead means the fallback stays visible until every suspended component within that boundary has finished loading, so the entire group appears together, all at once, as a single coherent unit exactly when it's genuinely fully ready to be shown. This grouping decision is a deliberate design choice about which pieces of a page should visually appear together as a unit versus which are independent enough to reasonably load and appear on their own separate timelines.

Exercises

MediumPractice using Handling Loading with Suspense in a real scenario.
View Solution
import React, { Suspense } from 'react';

const Chart = React.lazy(() => import('./Chart'));
const Table = React.lazy(() => import('./Table'));

function Dashboard() {
  return (
    <Suspense fallback={<p>Loading dashboard...</p>}>
      <Chart />
      <Table />
    </Suspense>
  );
}

Frequently Asked Questions

Why might wrapping several related lazy-loaded components in one single shared Suspense boundary be preferable to giving each one its own separate Suspense boundary?

If several related components, say a chart and its accompanying data table that are meant to be viewed together, each have their own separate Suspense boundary, they'll pop into view independently and potentially at quite different times depending on how quickly each one's code chunk happens to download, producing a jarring, staggered appearance where part of a logically unified section shows up well before the rest of it, which can look broken or incomplete even though nothing is actually wrong. Wrapping both components in one single shared Suspense boundary instead means the fallback stays visible until every suspended component within that boundary has finished loading, so the entire group appears together, all at once, as a single coherent unit exactly when it's genuinely fully ready to be shown. This grouping decision is a deliberate design choice about which pieces of a page should visually appear together as a unit versus which are independent enough to reasonably load and appear on their own separate timelines.

Related Functions

lazy-loadingerror-boundariesconditional-component-rendering