Extra JavaScript Means Lost Shoppers: Slim Down Your Store's Bundle
By Arash Latifi — Founder, The DevArt
Every kilobyte of JavaScript is waiting time on mobile. With real Turbopack benchmark numbers, see how a heavy bundle wrecks first load — and slim it down with a simple checklist.
TL;DR — Your JavaScript bundle is all the code a shopper's browser must download before your site works; on mobile, every kilobyte costs time. Real benchmarks from the Next.js team show that smarter code splitting cut requests from 76 to 24 on first load — with zero changes to how the site looks.
If you run a shop or a service site, nobody has probably ever asked you "how many kilobytes of JavaScript does my site load?" — yet that hidden number decides whether a mobile visitor waits or bounces. In the Core Web Vitals guide I covered why speed equals sales; here we tackle one of its main causes: the bundle.
What a bundle actually is
A concrete example from the official Turbopack team post (Next.js's bundler): nextjs.org is built from 355 JavaScript modules. There are three ways to deliver them to the browser:
- One file for everything: a single ~1.09 MB file loaded on every page. Later navigations are fast (cached), but even a page with almost no JavaScript ships the full payload.
- One file per page: files get slimmer, but shared code (like the footer) is duplicated into every page — a visitor opening four pages downloads the footer code four times.
- One file per module: no code is over-shipped, but that's 355 tiny network requests — and per the same post, gzip compresses many small files worse because repeated patterns only count within a single file.
So "least code" and "fewest requests" are conflicting goals, and the bundler has to strike a balance.
Real numbers: what good splitting is worth
The Next.js team tested their own site with three chunking configurations, running the same series of navigations:
| Configuration | Total downloaded | Requests | |---|---|---| | No merging (one chunk per module) | 561.6 KB | 96 | | Turbopack defaults | 554.8 KB | 38 | | Merge everything per group | 610.0 KB | 15 |
The instructive part: maximum merging produced the fewest requests but shipped 10% more code. Naive optimization can backfire. First page load went from 363.6 KB (76 requests) without merging to 344.2 KB (24 requests) with the defaults.
Why shop bundles get heavy
Usually not because of your own code:
- Third-party widgets: live chat, ad pixels, survey tools — each adds tens of kilobytes of separate scripts
- Heavy libraries for simple jobs: importing an entire UI library for two or three components
- Imports that don't tree-shake: unused code that ships anyway — newer Turbopack versions can tree-shake CommonJS modules too (
turbopackCjsTreeShaking), previously ESM only - Extra runtime code: bundlers usually ship helper runtime unconditionally; Turbopack 16.3/16.4 made it lighter (WebAssembly and Web Worker loading code ships only when actually used) and in 16.4 one shared runtime chunk replaces the per-page ones — per the announcement, about 10 KB less client-side JavaScript on every navigation after the first
Checklist: slim your bundle today
- [ ] Open DevTools (Network tab), hard-refresh your homepage with "Disable cache", and note two numbers: JS size and request count
- [ ] Compare third-party scripts against it — remove or delay any widget that doesn't drive sales
- [ ] If you're on Next.js, update to the latest 16.x; runtime improvements and the smaller disk cache (20–25% less space in 16.4) activate with no code changes
- [ ] Re-check PageSpeed Insights — mobile LCP is your headline metric
- [ ] After every big change (new widget, new library), re-check those same two Network-tab numbers so bundle growth gets caught early
On WordPress the same logic applies (widgets and plugins are just third-party scripts) — but don't fix bloat with a caching plugin; cut the payload first. For how this feeds rankings, see the technical SEO checklist.
FAQ
Q: How much JavaScript is "too much"?
There's no magic universal number — it depends on the page. Practical trick: compare a similar page on a faster competitor's site in the Network tab; a gap of a few hundred kilobytes means there's room to cut. The final arbiter is mobile LCP in PageSpeed Insights.
Q: My site is WordPress — not for me?
The principle is identical: every script that loads costs size and requests. The difference is control — via plugins and theme instead of bundler config. Removing unused plugins has the same effect as dropping a heavy library.
Q: Who should do this work?
On Next.js, a large share of the gains arrive free with a version update, and the rest is about one working session. On a crowded WordPress site, start by removing widgets yourself; if mobile LCP is still above 2.5 s after that, it's time to talk to a developer.