When using lazy loading in React with React.lazy()
, there’s a period of time when the component is being fetched but not yet available. Without a placeholder, the user would see nothing during that time.
Suspense
is React’s built-in solution for handling this gap — it lets you show a fallback UI while the component is loading.
What is Suspense
?
Suspense
is a React component that wraps around lazily loaded components and displays a fallback (e.g., a loading spinner or message) until they finish loading.
Basic syntax:
<Suspense fallback={<Loading />}>
<LazyComponent />
</Suspense>
Why is Suspense
needed during lazy loading?
- Without it, React doesn’t know what to render while the component is being downloaded.
- With it, the user sees a loading state instead of a blank screen.
- It prevents sudden UI jumps when the component finally appears.
Example Without Suspense
❌
const About = React.lazy(() => import('./About'));
export default function App() {
return (
<div>
<About /> {/* ❌ Will throw an error without Suspense */}
</div>
);
}
This will cause an error, because React.lazy requires a Suspense boundary.
Example With Suspense
✅
import React, { Suspense } from 'react';
const About = React.lazy(() => import('./About'));
export default function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<About />
</Suspense>
</div>
);
}
How it works:
- When
<About />
starts loading, React pauses rendering insideSuspense
. - The
fallback
content (e.g., “Loading…”) is shown. - Once
<About />
is ready, React replaces the fallback with the actual component.
Suspense with react-router-dom
import React, { Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
const Home = React.lazy(() => import('./pages/Home'));
const About = React.lazy(() => import('./pages/About'));
export default function App() {
return (
<Router>
<Suspense fallback={<div>Loading page...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</Router>
);
}
Here, the fallback UI is shown whenever a route’s component is still being fetched.
Best Practices
- Keep fallback UIs lightweight (spinner, skeleton loader, short text).
- Use nested Suspense boundaries for different sections (so not everything waits if only part of the page is loading).
- Avoid keeping users waiting too long — break up huge chunks of code into smaller lazy-loaded pieces.
✅ Key takeaway:
Suspense
is the safety net for lazy loading. Without it, React can’t render anything until the lazy-loaded component is ready, leading to errors or blank screens. With it, users see a smooth loading state while your app fetches components on demand.
Top comments (0)