Skip to content

Code Splitting

Code splitting breaks your JavaScript bundle into smaller chunks loaded on demand. Faster initial page load, better Core Web Vitals — especially on mobile networks.

Splitting Strategies

Route-based splitting: each page is a separate chunk via React.lazy. Component-based splitting: heavy charts/editors load only when feature opens. Vendor splitting: bundlers separate node_modules automatically.

Vite/Rollup analyze imports statically — dynamic import() expressions create split points.

// Vite creates separate chunks automatically
const Editor = lazy(() => import('./RichTextEditor'));
const Chart = lazy(() => import('./AnalyticsChart'));

// Analyze bundle
npm run build && npx vite-bundle-visualizer

Inspect chunk sizes after build to find overweight dependencies.

Split Points

import('./module')           // dynamic — split chunk
import lib from 'heavy-lib'   // static — in main/vendor chunk
// Move heavy-lib import inside dynamic import to split
  • Split at route boundaries first for maximum impact.
  • Defer heavy third-party libs (charts, editors) until needed.
  • Analyze bundle with rollup-plugin-visualizer or similar.
  • Tree-shake: import named exports, not entire libraries.

Code Splitting Tactics

Ways to reduce initial bundle size.

Tactic Benefit
Route lazy loading Smaller initial JS
Dynamic import libs Defer heavy dependencies
Tree shaking Remove unused exports
Analyze bundle Find surprise large deps
Replace libraries Smaller alternatives (date-fns vs moment)
Prefetch critical chunks Faster next navigation

Vendor and Common Chunks

Bundlers extract shared dependencies into vendor chunks cached separately. Changing app code doesn't invalidate vendor cache — good for repeat visitors.

Over-Splitting

Too many tiny chunks increase HTTP requests and latency. Balance chunk count — route + major feature splits usually suffice.

Common Mistakes

  • Importing entire lodash/moment instead of subpaths.
  • No bundle analysis — guessing what's large.
  • Splitting every component regardless of size.
  • Ignoring lazy load error handling.

Key Takeaways

  • Dynamic import() creates split points at build time.
  • Route-based splitting gives the best initial load wins.
  • Analyze bundles to target heavy dependencies.
  • Balance chunk count vs request overhead.

Pro Tip

Run bundle visualizer after adding any charting, PDF, or editor library — they're frequent bundle hogs.