patternjavascriptModerate
Code splitting with dynamic import() at the route level
Viewed 0 times
code splittingdynamic importReact.lazySuspenseroute splittingwebpack chunks
Error Messages
Problem
Shipping a single JavaScript bundle means every user downloads code for every route, even routes they will never visit. Initial parse and compile time is proportional to bundle size.
Solution
Use dynamic import() with React.lazy or a router-level split to load route code on demand.
// React.lazy with Suspense
const Dashboard = React.lazy(() => import('./pages/Dashboard'));
const Settings = React.lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
// Webpack magic comment for named chunk
const Admin = React.lazy(
() => import(/ webpackChunkName: "admin" / './pages/Admin')
);
// React.lazy with Suspense
const Dashboard = React.lazy(() => import('./pages/Dashboard'));
const Settings = React.lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
// Webpack magic comment for named chunk
const Admin = React.lazy(
() => import(/ webpackChunkName: "admin" / './pages/Admin')
);
Why
Route-level splitting is the highest-impact split point because entire pages are never shared. Users on the homepage pay zero cost for the dashboard bundle. Webpack/Rollup/Vite all support this natively via dynamic import().
Gotchas
- Suspense fallback must be shown to prevent a blank screen during load — always wrap lazy components
- Prefetch likely next routes with <link rel="prefetch"> or webpack prefetch comments to hide latency
- Component-level splits inside a route add waterfall risk — prefer route-level splits first
- SSR: React.lazy does not support SSR; use loadable-components or Next.js dynamic() instead
Code Snippets
Prefetch vs preload with webpack magic comments
// Webpack prefetch: browser downloads in idle time
const HeavyModal = React.lazy(
() => import(/* webpackPrefetch: true */ './HeavyModal')
);
// Webpack preload: browser downloads with current chunk
const CriticalPanel = React.lazy(
() => import(/* webpackPreload: true */ './CriticalPanel')
);Context
When reducing initial bundle size for multi-page or multi-route applications
Revisions (0)
No revisions yet.