PageSpeed Matters
    PageSpeed Matters
    Optimization Techniques · Glossary

    Code Splitting · Definition & Explanation 2026

    Code splitting is a build-time optimization that breaks a monolithic JavaScript bundle into multiple smaller chunks loaded on demand — typically when the user navigates to a route or interacts with a feature that requires the code. Instead of forcing users to download the entire application upfront, code splitting delivers only the JavaScript needed for the current view.

    For a typical React SPA, code splitting can reduce the initial bundle from 500KB–2MB down to 100–200KB, dramatically improving First Contentful Paint (FCP), Largest Contentful Paint (LCP), and Total Blocking Time (TBT). The deferred chunks are loaded asynchronously in the background or when the user navigates to a new route.

    Modern bundlers like Vite (Rollup), Webpack, and esbuild support code splitting natively via the dynamic `import()` syntax. React provides `React.lazy()` and `Suspense` for component-level splitting. Next.js, Remix, and other frameworks implement route-based splitting automatically.

    In 2026, code splitting is table stakes for any JavaScript-heavy application. Combined with tree shaking and lazy loading, it forms the foundation of an efficient loading architecture. Pages that don't code-split typically fail TBT (> 200ms), have poor INP, and load 3–5× more JavaScript than necessary on initial page load.

    Updated 2026-02-28
    M
    By Matt Suffoletto

    TL;DR — Quick Summary

    Code splitting divides JavaScript into smaller chunks loaded on demand rather than all upfront. Use route-based splitting (automatic in frameworks), React.lazy() for component-level splitting, and dynamic import() for feature-level splitting. Target ≤ 200KB initial bundle.

    What is Code Splitting?

    Code splitting breaks a JavaScript application into multiple smaller bundles (called 'chunks') that are loaded on demand rather than all at once. The browser downloads only the JavaScript needed for the current view, deferring the rest until it's needed.

    Implementation levels:

    • Route-based splitting — Each page/route gets its own chunk. When the user navigates to /dashboard, only the dashboard code loads. This is the most impactful level and is automatic in frameworks like Next.js, Remix, and Gatsby.
    • Component-level splitting — Individual components are loaded on demand using React.lazy() + Suspense. Ideal for heavy components like charts, editors, modals, and admin panels.
    • Feature-level splitting — Specific features or libraries are loaded when triggered. For example, loading a PDF library only when the user clicks 'Export PDF.'

    All three levels use the dynamic `import()` syntax under the hood. The bundler analyzes import() calls at build time and creates separate chunk files.

    History & Evolution

    Key milestones:

    • 2014 — Webpack introduces code splitting via require.ensure().
    • 2015 — Dynamic import() proposal begins TC39 process.
    • 2017 — React 16.6 introduces React.lazy() and Suspense for component-level code splitting.
    • 2018 — Dynamic import() becomes standard JavaScript. Webpack, Rollup, and Parcel all support it.
    • 2020 — Next.js popularizes automatic route-based splitting — developers get code splitting 'for free.'
    • 2023 — React Server Components introduce a new paradigm: server components don't ship JavaScript to the client at all.
    • 2025–2026 — Vite (Rollup) is the dominant bundler with automatic code splitting. Framework-level splitting is the norm.

    How Code Splitting is Measured

    Code splitting effectiveness is measured by comparing bundle sizes before and after:

    Tools for analysis:

    • Bundle analyzers — rollup-plugin-visualizer (Vite), webpack-bundle-analyzer (Webpack) show visual treemaps of bundle contents and chunk sizes.
    • Chrome DevTools Coverage tab — Shows what percentage of loaded JavaScript is actually used. High unused % indicates splitting opportunities.
    • Lighthouse — 'Reduce unused JavaScript' audit identifies code that could be split or deferred.

    Key rule: Field data (CrUX) determines Google rankings. Lab data (Lighthouse, WebPageTest) is for debugging and iteration.

    Common Causes of Poor Code Splitting Scores

    Common issues that indicate missing or poor code splitting:

    1. 1Single large bundle — All application code in one file (vendor.js or main.js > 500KB).
    2. 2All routes loaded upfront — SPA loads dashboard, settings, admin code on the homepage.
    3. 3Heavy libraries loaded globally — Chart.js, Monaco Editor, PDF.js imported in the main bundle.
    4. 4Barrel file imports — `import { Button } from '@/components'` may pull in every component.
    5. 5No framework-level splitting — Custom React Router setup without lazy routes.

    Frequently Asked Questions

    Struggling with Code Splitting?

    Request a free speed audit and we'll identify exactly what's holding your scores back.