JavaScript PerformanceLesson 4.2
How to code-split a JavaScript bundle with dynamic imports
dynamic import(), route-based splitting, component-level splitting, Webpack/Vite code splitting, prefetch, preload hints, React.lazy, loading states
Code Splitting with Dynamic Imports
Code splitting breaks a monolithic bundle into smaller chunks loaded on demand. Users download only what they need for the current page, reducing initial parse and execution cost directly.
The native browser API is import():
// Static import — always in the initial bundle
import { heavyChart } from './chart-library';
// Dynamic import — separate chunk, loaded on demand
const renderChart = async () => {
const { heavyChart } = await import('./chart-library');
heavyChart('#container', data);
};In React, combine with React.lazy and Suspense for route-level splitting:
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
export function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}Prefetch chunks the user will likely need next using a magic comment:
const Settings = lazy(() =>
import(/* webpackPrefetch: true */ './pages/Settings')
);Vite handles code splitting automatically at the import() boundary — no configuration needed. Webpack requires the optimization.splitChunks config or dynamic imports to trigger splitting.
