What Is Lazy Loading in React?
Learn how React.lazy and Suspense enable lazy loading, why it shrinks bundle size, and how to code-split routes and heavy components for speed.
Expected Interview Answer
Lazy loading in React is the technique of deferring a component's code until it is actually needed, using `React.lazy()` combined with dynamic `import()` and a `Suspense` boundary to show a fallback while the chunk loads.
Instead of bundling every component into one large JavaScript file that the browser must download upfront, `React.lazy(() => import('./Component'))` tells the bundler to split that component into its own chunk. The chunk is only fetched over the network the first time the component is actually rendered, and `Suspense` lets you declare a loading fallback for that wait. This is commonly applied to routes, modals, and heavy widgets that are not needed on initial page load, directly shrinking the JavaScript needed for first paint and improving metrics like LCP and Time to Interactive.
- Shrinks the initial JavaScript bundle size
- Improves first paint and Time to Interactive
- Loads heavy components only when actually rendered
- Pairs naturally with route-based code splitting
- Reduces wasted bandwidth for unused features
AI Mentor Explanation
Lazy loading is like a team not flying in the specialist spin bowler until the pitch report actually calls for spin, rather than bringing in every possible specialist before the toss. The squad only pays that cost for the player the moment the match situation demands them, and until then a simple blank slot on the team sheet shows 'awaiting selection' so nobody assumes the position is empty.
Step-by-Step Explanation
Step 1
Wrap the import in React.lazy
Call `React.lazy(() => import('./HeavyComponent'))` so the bundler treats it as a separate code-split chunk instead of part of the main bundle.
Step 2
Wrap usage in Suspense
Render the lazy component inside `<Suspense fallback={<Spinner />}>` so React has a defined UI to show while the chunk downloads.
Step 3
Chunk fetches on first render
The browser only requests that JavaScript chunk the first time the component is actually rendered, not during initial page load.
Step 4
Fallback shows during the wait
React displays the Suspense fallback until the dynamic import resolves, then swaps in the real component seamlessly.
Step 5
Apply at routes and heavy widgets
Common targets are route-level pages, modals, charts, and rich editors — anything not needed for the very first paint.
What Interviewer Expects
- Knows React.lazy pairs with dynamic import() and code splitting
- Understands Suspense provides the loading fallback
- Can explain the bundle-size and Core Web Vitals benefit
- Names realistic use cases like routes and modals
- Aware of error boundaries for handling failed chunk loads
Common Mistakes
- Lazy-loading components needed for the initial LCP content
- Forgetting to wrap lazy components in a Suspense boundary
- Not handling chunk load failures with an error boundary
- Assuming lazy loading works for named exports without a default export wrapper
Best Answer (HR Friendly)
“Lazy loading means the app only downloads the code for a screen or feature when a user actually needs it, instead of loading everything upfront. This makes the initial page load noticeably faster, especially on mobile.”
Code Example
import { lazy, Suspense } from 'react';
// Code-split: this chunk downloads only when the route renders
const SettingsPage = lazy(() => import('./SettingsPage'));
function App() {
return (
<Suspense fallback={<div>Loading settings…</div>}>
<SettingsPage />
</Suspense>
);
}Follow-up Questions
- How does React.lazy differ from dynamic import() on its own?
- What happens if a lazy-loaded chunk fails to fetch over the network?
- How does lazy loading interact with server-side rendering?
- When should you avoid lazy-loading a component?
- How do you lazy-load a named export instead of a default export?
MCQ Practice
1. What two React features combine to implement lazy loading?
React.lazy defines the dynamically imported component and Suspense provides the fallback UI while it loads.
2. When does a lazy-loaded component's code actually get fetched?
The dynamic import chunk is requested over the network the first time the lazy component is rendered, not before.
3. What is a common real-world target for lazy loading in a React app?
Routes, modals, and heavy widgets not needed for first paint are ideal lazy-loading candidates since they defer non-critical code.
Flash Cards
What does React.lazy() do? — It wraps a dynamic import() so the component's code is split into its own chunk, loaded on demand.
What must wrap a lazy component? — A Suspense boundary with a fallback prop to display while the chunk downloads.
What Core Web Vitals metrics does lazy loading help? — LCP and Time to Interactive, by shrinking the JavaScript needed for the first render.
How do you handle a failed lazy chunk load? — Wrap the Suspense boundary in an error boundary to catch and gracefully handle the fetch failure.