Skip to content
Performance Optimizationhigh

React.lazy & Code Splitting

React.lazy enables code splitting by loading components dynamically via dynamic import(). Combined with Suspense, it shows a fallback while the component's code is being fetched over the network.

Memory anchor

React.lazy is like a library's reserve section — the book (component code) isn't on the shelf until you request it. Suspense is the 'fetching your book' sign while you wait.

Expected depth

Usage: const LazyChart = lazy(() => import('./Chart')). Wrap in <Suspense fallback={<Spinner />}>. The component's code is split into a separate bundle chunk that's only downloaded when first rendered. Route-based splitting is the most impactful — split each page into its own chunk. Named exports need a wrapper: lazy(() => import('./utils').then(m => ({ default: m.Chart }))). Preloading can improve UX: trigger the import() on hover/focus before the user navigates.

Deep — senior internals

Under the hood, lazy() creates a component that throws a promise during its first render. Suspense catches this promise (using the error boundary mechanism), renders the fallback, and re-renders when the promise resolves. This is the same mechanism used for data fetching with Suspense-compatible libraries. In SSR with streaming, lazy components can be loaded server-side too — the code still splits for the client bundle, but the server renders the component immediately. React.lazy doesn't support Server Components directly; server components are inherently code-split because they never ship to the client.

🎤Interview-ready answer

React.lazy with Suspense enables code splitting — loading component code on demand. I use it primarily for route-based splitting, which has the highest impact. The mechanism works by throwing a promise that Suspense catches, showing a fallback until the code loads. I preload chunks on hover for better UX and combine with route prefetching in frameworks like Next.js.

⚠Common trap

Using React.lazy for every small component. The overhead of an extra network request can outweigh the bundle savings for tiny components. Split at meaningful boundaries: routes, modals, heavy visualizations.

Related concepts