
Code Splitting
- 1 installs
- 73.4k repo stars
- Updated June 18, 2026
- thedaviddias/frontendchecklist
Converts large static imports to dynamic import() and splits routes so users only download the code the current page needs.
About
A frontend-checklist JavaScript rule for splitting large bundles to improve Time to Interactive. A developer uses it when a heavy SPA bundle blocks interactivity for seconds.
- Use dynamic import() to load code only when needed
- Split routes and lazy-load heavy third-party libraries
Code Splitting by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,914 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedaviddias/frontendchecklist --skill code-splittingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 73.4k |
| Last updated | June 18, 2026 |
| Repository | thedaviddias/frontendchecklist ↗ |
What it does
Converts large static imports to dynamic import() and splits routes so users only download the code the current page needs.
Files
Split large JavaScript bundles
A 500 KB JavaScript bundle blocks page interactivity for 3–5 seconds on a mid-range mobile device even after the bytes arrive — JS must be parsed and compiled before execution. Code splitting means users only download and parse the code they actually need for the current page, dramatically improving Time to Interactive.
Quick Reference
- Use dynamic import() to load code only when it's actually needed
- Split routes in SPAs so each page loads only its own code
- Lazy-load heavy third-party libraries (chart libraries, rich text editors)
- Analyze your bundle with a visualizer to find what to split
Check
Identify any large third-party imports or feature modules in this file that could be loaded lazily with dynamic import() instead of statically.
Fix
Convert the identified static imports to dynamic imports using import() and add appropriate loading states.
Explain
Explain JavaScript code splitting, how dynamic import() works, and how to implement route-based splitting in a SPA.
Code Review
Inspect route modules, heavy feature imports, and third-party libraries loaded on initial render. Flag dependencies that can move behind import(), route boundaries, or user-triggered flows without breaking the first meaningful paint.
---
For full implementation details, code examples, and framework-specific guidance, see references/rule.md.
Rule page: https://frontendchecklist.io/en/rules/javascript/code-splitting
Split large JavaScript bundles
Use dynamic imports and route-based code splitting to break large bundles into smaller chunks that load on demand, reducing initial page load time.
Priority: high · Difficulty: intermediate · Time: 25 min
--- Code splitting uses `import()` and route boundaries to divide your JavaScript application into separate chunks that load on demand rather than all at once.
Code Example
// ❌ Static import loads everything upfront
// ✅ Dynamic import loads only when needed
async function handleExportClick() {
const { generatePDF } = await import('./pdf-generator.js')
generatePDF(document)
}Why It Matters
A 500 KB JavaScript bundle blocks page interactivity for 3–5 seconds on a mid-range mobile device even after the bytes arrive — JS must be parsed and compiled before execution. The web.dev dynamic imports guide focuses on this exact win: users only download and parse the code they actually need for the current page.
Route-Based Splitting (React)
// Each route is its own chunk — users download code for the page they visit
const Dashboard = lazy(() => import('./pages/Dashboard'))
const Settings = lazy(() => import('./pages/Settings'))
const Reports = lazy(() => import('./pages/Reports'))
function App() {
return (
}>
} />
} />
} />
)
}Lazy-Loading Heavy Components
// Rich text editors, chart libraries, map components
const RichEditor = lazy(() => import('./RichEditor'))
const ChartPanel = lazy(() => import('./ChartPanel'))
function PostEditor({ showChart }) {
return (
<div>
}>
{showChart && (
}>
)}
</div>
)
}Conditional Feature Loading
// Load analytics only in production
if (process.env.NODE_ENV === 'production') {
import('./analytics.js').then(({ init }) => init())
}
// Load a polyfill only when needed
async function setupApp() {
if (!window.ResizeObserver) {
await import('resize-observer-polyfill')
}
initApp()
}Preloading for Anticipated Navigation
// Preload the next likely page without executing it yet
function prefetchSettingsPage() {
import(/* webpackPrefetch: true */ './pages/Settings')
}
// Trigger on hover — user is likely about to click
settingsLink.addEventListener('mouseenter', prefetchSettingsPage)Analyzing Your Bundle
A first pass with Webpack Bundle Analyzer or Bundlephobia usually shows which dependency or route should move behind import().
# With Vite
pnpm exec vite-bundle-visualizer
# With webpack
pnpm exec webpack-bundle-analyzer stats.json
# With source-map-explorer
pnpm exec source-map-explorer 'build/static/js/*.js'Verification
Automated Checks
- Compare the before/after output from your bundle visualizer and confirm the initial chunk shrinks meaningfully; `import()` should move real code out of the initial graph rather than only reshuffle file names.
- Test the loading state or suspense fallback so deferred features still feel intentional to users.
- Re-run Lighthouse or your performance budget check to confirm the split improves initial JS cost instead of only moving bytes around.
- If your project uses a JS budget, keep the initial bundle within that threshold rather than only moving bytes into slightly later chunks; a common starting point is
<= 150 KBgzipped for the main route bundle.
Manual Checks
- Verify the lazy-loaded code is not downloaded on first load unless the current route or interaction needs it.