Reducing JavaScript Bloat in Shopify Themes
Table of Content
A Melbourne homewares merchant rang Claire after a frustrating quarter. Their Shopify theme had been customised by three different developers over five years, picked up a dozen apps along the way, and was now shipping 1.4 megabytes of JavaScript on every product page. Lighthouse was screaming at them, mobile conversion had slid 18 per cent year on year, and the founder could feel the lag every time she opened the site on her phone in a cafe. The brief was direct: cut the JavaScript without breaking anything. Six weeks later we had the bundle down to 320 kilobytes and Time to Interactive on mobile had halved. Here is the playbook we used, and the lessons that apply to any Australian Shopify store carrying too much script weight.
Start with an honest bundle analysis
You cannot fix what you cannot see. The first job on any JavaScript audit is to produce a complete inventory of every script the store loads, where it comes from, and what it weighs. Open the network tab in Chrome DevTools, filter by JavaScript, and capture the totals on a cold load. Then sort by transfer size, ignoring anything under 5 kilobytes for now.
Pair this with a source-map-aware tool. Webpack Bundle Analyzer or esbuild’s metafile viewer will show you exactly which modules contribute to your theme’s compiled bundle. For the third-party scripts pulled in by apps, use the Coverage tab in DevTools to measure how much of each file actually executes on the page. Most apps ship code paths for features you never use, and that unused code still costs parse and compile time.
Document the findings in a spreadsheet with columns for source, size, purpose, and whether the script is critical for first paint. This becomes your removal worklist.
Remove jQuery if you can
jQuery still ships in a surprising number of Shopify themes, often pulled in by an older theme base or a single app that has a dependency on it. The library itself is around 85 kilobytes minified, and modern browsers do not need it. Every selector, animation, and AJAX call jQuery offers has a native equivalent that is faster, smaller, and better supported.
Audit your theme files for $ and jQuery references. Replace document.ready handlers with DOMContentLoaded listeners. Replace .ajax with fetch. Replace .css and .addClass with element.style and classList. Replace .on click handlers with addEventListener. For animations, CSS transitions and the Web Animations API cover almost every real use case.
If a single app is forcing you to keep jQuery, talk to the vendor or replace the app. We have helped merchants swap dependency-heavy review widgets and currency converters for lighter alternatives, sometimes recovering 120 kilobytes in a single move.
Tree-shaking and code-splitting in theme JavaScript
If you are building theme JavaScript with a modern bundler, tree-shaking should already be on by default. The catch is that tree-shaking only works when your code uses ES modules and your dependencies are written in a way the bundler can statically analyse. Avoid star imports. Import only the named exports you actually use.
Code-splitting is the bigger lever. Modern Shopify themes should ship a small core bundle that loads on every page, plus separate chunks loaded on demand for product pages, cart drawers, search overlays, and any other route-specific behaviour. Use dynamic import statements wrapped in event listeners. A search overlay only needs its JavaScript when the user clicks the search icon. A cart drawer only needs its JavaScript when the customer adds the first item.
This pattern alone can cut your initial JavaScript payload by 40 to 60 per cent on a typical theme. It also improves Time to Interactive dramatically because the main thread is not blocked parsing code the customer may never trigger.
Vanilla JS patterns that replace framework habits
Many developers reach for a framework because they are used to its patterns, not because the site genuinely needs one. For most Shopify theme work, vanilla JavaScript with a few small utilities does the job at a fraction of the weight. A handful of patterns cover most theme needs.
- Custom Elements for reusable components. Wrap a quick-add button, a quantity selector, or a variant picker in a class that extends HTMLElement. Browser support is universal and the code reads cleanly.
- Intersection Observer for lazy loading and reveal animations. Lighter and faster than any scroll-listener library.
- Event delegation on a single document-level listener for click and submit handlers, rather than attaching individual listeners to every product card.
- Web Components and the template element for client-side templating without a runtime library.
Adopting these patterns lets you delete utility libraries that exist purely to paper over what the browser already does well. The Shopify Dawn theme is built largely on this approach and remains a useful reference. Our deep dive into Liquid performance optimisation covers how to wire these JavaScript patterns into Liquid sections without duplication.
Defer everything that is not critical
Even after you have trimmed the bundle, the order in which scripts load matters enormously. Anything not required to render the first viewport should defer until after the page is interactive. That includes analytics, marketing pixels, chat widgets, review carousels below the fold, and most app embeds.
Use the defer attribute on script tags wherever possible, and async only where execution order does not matter. For third-party scripts you do not control directly, load them after the load event fires, or after a short timeout, so they never compete with the page’s own JavaScript for main thread time.
Chat widgets are a particular offender. Most send 100 to 300 kilobytes of JavaScript on first load, often blocking. Loading the chat widget only after a user idle event, or behind a click on a custom button, recovers serious budget without removing the feature. Our guide to auditing Shopify apps for performance walks through this evaluation in detail.
Watch out for app trojan horses
Some Shopify apps inject far more JavaScript than their feature warrants. A simple announcement bar might pull in a full React runtime. A review widget might load a polyfill for browsers no one in Australia uses anymore. When you audit, treat every app embed as suspect until proven innocent.
For apps that earn their place but ship too much code, contact the vendor with specific numbers. Many will offer a lighter integration option or roadmap a fix. For apps that cannot be improved, decide whether the feature justifies the cost. We have removed apps doing $200 a month in attributable revenue because they cost $2,000 a month in lost conversions through page weight.
Monitor continuously, not just at launch
JavaScript bloat creeps back in. A new app, a tag manager change, a marketing tracker added for a campaign and never removed: any of these can undo months of optimisation work. Set up a monitoring routine that catches regressions before they hurt customers.
- Run Lighthouse CI against your staging environment on every theme deploy and fail the build if the JavaScript budget exceeds your threshold.
- Track real-user JavaScript execution time through the Performance API, sent to your analytics tool.
- Review the Chrome User Experience Report monthly for Interaction to Next Paint regressions.
- Audit app installs quarterly, removing anything that has not justified its weight in the previous 90 days.
For Australian merchants on slower regional connections, every kilobyte counts more than it does in Sydney CBD. The customers most likely to convert on a fast site are also the ones most likely to abandon a slow one.
Where to start
The Melbourne homewares store recovered measurable conversion and went on to ship faster releases because the codebase finally fit in their developers’ heads. JavaScript discipline is not a one-off project; it is a habit. If you want a clear picture of where your store stands today, our team runs structured audits that produce a prioritised action list with effort estimates. Take a look at our Sydney web development services, or start a project with a conversation about your current bundle weight.
