Code splitting is the practice of breaking a website’s JavaScript into smaller chunks that load on demand instead of shipping one large bundle on first visit. It speeds up initial render, lowers the amount of script the browser must parse before a page becomes interactive, and directly improves Core Web Vitals like Largest Contentful Paint and Interaction to Next Paint.
What Code Splitting Actually Does
When a browser loads a page, it has to download, parse, compile, and execute every byte of JavaScript before that code can run. A monolithic bundle forces the visitor to wait for code they may never use, like the checkout logic on a homepage or an analytics dashboard widget buried three clicks deep. Code splitting solves this by carving the bundle into route-based and component-based chunks. The browser only fetches the JavaScript needed for the current view, then lazily loads the rest as the user navigates.
The concept has two main flavors. Route-based splitting loads a separate chunk per page, so the homepage never ships the pricing page’s code. Component-based splitting defers heavy individual components, like a video player, a charting library, or a modal, until the moment they are actually needed. Both reduce the critical JavaScript that blocks interactivity on first paint.
Why Code Splitting Matters for Performance and Rankings
Google measures real-user experience through Core Web Vitals, and JavaScript is one of the biggest contributors to poor scores. A bloated main thread delays interactivity, inflates Interaction to Next Paint, and can push back the Largest Contentful Paint element if rendering depends on hydration. Smaller, targeted chunks mean less main-thread work, faster time to interactive, and a more responsive feel.
The business case is just as concrete. Slow sites lose conversions. Studies across e-commerce and SaaS consistently show that every additional second of load time depresses signups, add-to-cart rates, and lead form completions. Search rankings compound the loss, since Core Web Vitals are a confirmed ranking signal and a poor mobile experience suppresses visibility. If you want the full picture on how these metrics tie together, our guide on Core Web Vitals and SEO breaks down the connection in detail.
The Hidden Cost of Unused JavaScript
Most sites ship far more JavaScript than any single visitor uses. Third-party libraries, polyfills for browsers nobody on your audience runs, and feature code for pages a user never opens all pile into the initial download. Code splitting is the mechanism that lets you keep that functionality available without forcing every visitor to pay for it upfront.
How to Diagnose Code Splitting Problems
You cannot fix what you have not measured. Start with these diagnostic steps before touching any code.
- Lighthouse: Run an audit in Chrome DevTools or via the command line. Look for the “Reduce unused JavaScript” and “Reduce JavaScript execution time” opportunities. Lighthouse estimates the kilobytes you could save.
- PageSpeed Insights: Enter your URL at the PageSpeed Insights site for both lab and field data. Field data from the Chrome User Experience Report tells you how real visitors experience the page, which matters more than a single lab run.
- Coverage tab: In Chrome DevTools, open the Coverage panel, reload the page, and see exactly which JavaScript bytes executed versus sat unused. Red bars signal candidates for splitting or removal.
- Bundle analyzer: If you control the build, a visual bundle analyzer maps which modules contribute the most weight. This is where you find the surprise 300 KB date library imported for one function.
Reading the Numbers
A healthy initial JavaScript payload for a marketing site sits well under 200 KB compressed. If Lighthouse flags more than 100 KB of unused JavaScript on first load, you have clear room to split. Pair this with the Coverage data to confirm which chunks are dead weight on the entry route.
Concrete Fixes for Code Splitting
Once you know where the bloat lives, apply these techniques in order of impact.
1. Split by Route
Make each page or major route its own chunk. This is the single highest-leverage change for multi-page sites because it guarantees a visitor never downloads code for pages they have not visited. In a React application, dynamic imports paired with lazy loading handle this cleanly.
2. Lazy-Load Heavy Components
Defer anything large and non-critical to the first paint. Carousels, embedded maps, rich text editors, and charting libraries should load only when scrolled into view or triggered by interaction. In React this looks like:
const Chart = React.lazy(() => import('./Chart'));
Wrap the lazy component in a suspense boundary with a lightweight fallback so the layout stays stable and you avoid layout shift.
3. Defer Third-Party Scripts
Tag managers, chat widgets, and analytics rarely need to block render. Load them with the defer or async attribute, or initialize them after the page becomes interactive. This keeps third-party weight off the critical path.
4. Tree-Shake and Replace Heavy Dependencies
Import only the functions you use rather than entire libraries. Swap oversized dependencies for lighter alternatives where the feature set allows. Tree shaking removes dead exports at build time, but it only works when you import granularly.
How Modern Stacks Handle Code Splitting
The good news is that modern platforms automate most of this work, which is a large part of why they outperform legacy stacks on performance metrics.
Next.js
Next.js performs automatic route-based code splitting out of the box. Every page becomes its own bundle, and shared code is extracted into common chunks. The framework also supports dynamic imports through its built-in dynamic utility, which makes component-level lazy loading a one-line change. Server components and streaming further reduce the JavaScript shipped to the browser, since rendering happens on the server and only the interactive pieces hydrate on the client.
Framer
Framer handles code splitting and bundle optimization at the platform level, so you do not hand-tune webpack configs or write dynamic import boilerplate. Pages are split automatically, assets are served from a global CDN, and the rendered output is optimized for fast first paint. This is one of the reasons we build exclusively on the platform. You get the performance characteristics of a carefully engineered Next.js setup without the engineering overhead. Our breakdown of website speed optimization covers how these defaults stack up against a typical WordPress or Webflow build.
| Platform | Route splitting | Component lazy load | Manual config needed |
|---|---|---|---|
| Framer | Automatic | Automatic | None |
| Next.js | Automatic | Dynamic import | Minimal |
| WordPress | Manual or plugin | Manual | Significant |
Code Splitting Checklist
- Audit unused JavaScript in Lighthouse and the Coverage tab
- Confirm route-based splitting is active for every page
- Lazy-load any component over roughly 30 KB that is not visible on first paint
- Defer or async all non-critical third-party scripts
- Tree-shake imports and replace heavy dependencies
- Re-run PageSpeed Insights and compare field data before and after
A Practical Workflow for Splitting an Existing Site
Theory is useful, but most teams arrive at code splitting with a site that already feels slow. Here is the sequence we follow when auditing an existing build, ordered so that the largest wins come first and you can stop once the numbers clear the thresholds you care about.
Start by capturing a baseline. Run PageSpeed Insights on your three most important pages, the homepage, your highest-traffic landing page, and a deep conversion page like checkout or signup, and record the field data for Largest Contentful Paint and Interaction to Next Paint. Without a baseline you cannot prove whether a change helped, and it is easy to chase lab improvements that never reach real users.
Next, open the Coverage tab and reload each page. The unused percentage tells you how much of the initial bundle is dead weight on that route. If the homepage executes only thirty percent of its JavaScript on load, the other seventy percent belongs in lazy-loaded chunks or other routes entirely. This single measurement usually points straight at the biggest opportunity.
Then confirm route-based splitting is active. On a modern framework it usually is, but legacy builds and some single-page applications ship one bundle for the whole site. If that is your situation, route splitting is the first and largest change to make, because it stops every visitor from downloading code for pages they never open.
After routes, work down the list of heavy components. Sort your bundle analyzer treemap by size and lazy-load anything large that is not visible on first paint. Editors, charts, maps, video players, and date pickers are the usual suspects. Each one you defer is main-thread time the browser does not spend before the page becomes interactive.
Finally, re-test against your baseline and verify the field data moved, not just the lab score. Improvements in Lighthouse that do not show up in the Chrome User Experience Report after a few weeks usually mean the change helped a synthetic test more than real visitors. Performance work is only finished when the people loading your site actually feel it. Our broader website speed optimization guide places this workflow in the context of the other levers worth pulling.
Code splitting is one of the highest-return performance investments you can make, and on the right platform it requires almost no manual effort. If you want a site that ships lean JavaScript by default and scores well on Core Web Vitals without ongoing maintenance, see what we build on our portfolio or get a quote on our pricing page.
Frequently Asked Questions
Does code splitting hurt SEO?
No. When implemented correctly, code splitting improves SEO because it speeds up rendering and improves Core Web Vitals, which are ranking signals. The one caveat is that content critical for indexing should render server-side or be present in the initial HTML, so search engines do not depend on lazy-loaded chunks to discover important content.
What is the difference between code splitting and lazy loading?
Code splitting is the build-time process of breaking a bundle into smaller chunks. Lazy loading is the run-time strategy of fetching those chunks only when they are needed. They work together: code splitting creates the separate files, and lazy loading decides when the browser downloads them.
Do I need to configure code splitting on Framer?
No. Framer handles route-based splitting, asset optimization, and CDN delivery automatically. You build visually and the platform ships optimized, split output, which is why Framer sites tend to score well on PageSpeed Insights without manual tuning.
