Lazy Loading
React.lazy loads components dynamically via import(). Wrap lazy components in <Suspense> with a fallback while the chunk downloads. Standard pattern for route-level code splitting.
Dynamic import() for Components const Page = lazy(() => import('./Page')) tells the bundler to create a separate chunk loaded on demand when Page first renders.
Suspense fallback shows loading UI during chunk fetch — spinners, skeletons, or null for fast networks.
import { lazy, Suspense } from 'react';
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<PageSkeleton />}>
<Settings />
</Suspense>
);
} Each lazy import typically becomes its own JS chunk in Vite/Webpack output.
Lazy + Suspense Pattern const Component = lazy(() => import('./Component'));
<Suspense fallback={<Spinner />}>
<Component />
</Suspense> lazy() must wrap a function returning import() promise. Named exports: import('./mod').then(m => ({ default: m.Named })). Suspense boundary required above lazy component. Nested Suspense boundaries enable granular loading states. Lazy Loading Reference Common lazy loading patterns.
Pattern Example Default export lazy(() => import('./Page')) Named export .then(m => ({ default: m.Page })) Route lazy element: lazy(() => import(...)) with Suspense Fallback <Suspense fallback={...}> Preload import('./Page') on hover/link intent Error Error boundary around Suspense
Lazy Routes in React Router Wrap route tree or individual route elements in Suspense. Some setups lazy-load page components at route definition.
const Dashboard = lazy(() => import('./Dashboard'));
<Route path="/dash" element={
<Suspense fallback={<Spinner />}><Dashboard /></Suspense>
} /> Preloading on User Intent Call dynamic import on link hover/focus to start loading before navigation — reduces perceived wait.
Common Mistakes Forgetting Suspense wrapper around lazy components. Lazy loading tiny components — overhead not worth it. Not handling chunk load failures. Default vs named export import mismatch. Key Takeaways React.lazy defers loading component code until needed. Suspense provides fallback UI during chunk load. Ideal for route-level and heavy feature splitting. Combine with error boundaries for failed loads.
Pro Tip
Lazy load routes and heavy modals first — biggest bundle wins with least complexity.
React.memo Go to next item