Skip to main content

Code Splitting and Lazy Loading

React.lazy

import { lazy, Suspense } from 'react';

// Lazy load components
const Dashboard = lazy(() => import('./Dashboard'));
const Profile = lazy(() => import('./Profile'));
const Settings = lazy(() => import('./Settings'));

function App() {
return (
<Suspense fallback={<LoadingSpinner />}>
<Routes>
<Route path='/dashboard' element={<Dashboard />} />
<Route path='/profile' element={<Profile />} />
<Route path='/settings' element={<Settings />} />
</Routes>
</Suspense>
);
}

Route-Based Code Splitting

const routes = [
{
path: '/',
component: lazy(() => import('./pages/Home')),
},
{
path: '/about',
component: lazy(() => import('./pages/About')),
},
{
path: '/products',
component: lazy(() => import('./pages/Products')),
},
];

function App() {
return (
<Suspense fallback={<PageLoader />}>
<Routes>
{routes.map(({ path, component: Component }) => (
<Route key={path} path={path} element={<Component />} />
))}
</Routes>
</Suspense>
);
}

Dynamic Import

function loadComponent(componentName: string) {
return lazy(() => import(`./components/${componentName}`));
}

// Preload on hover
function ProductCard({ product }) {
const handleMouseEnter = () => {
import('./ProductModal'); // Preload
};

return <div onMouseEnter={handleMouseEnter}>{product.name}</div>;
}

Best Practices

  1. Split by routes - Each route gets own bundle
  2. Split by features - Large features in separate bundles
  3. Preload on interaction - Load before needed
  4. Show loading states - Use Suspense fallback
  5. Error boundaries - Handle loading failures