Your store has 22 apps installed. You can name maybe eight of them off the top of your head. The rest were added by a former employee, a developer who’s long gone, or during a “let’s try this” phase eighteen months ago, and every single one of them might still be loading a script on every page of your store, whether it’s doing anything useful or not.
This is app bloat, and it’s one of the most common issues we find when we run a Shopify audit for a store that’s “always felt a bit slow” but nobody can pinpoint why. The good news is that finding the culprits isn’t guesswork. It’s a repeatable process using free tools that are already sitting in your browser.
This post walks through exactly how to do that audit yourself: what to look for in your theme code, how to read a network waterfall, how to use Lighthouse and PageSpeed Insights properly (not just glance at the score), and a clear framework for deciding whether to keep, replace, or remove each app you find.
Why Shopify Apps Cause Bloat in the First Place
Most Shopify apps that touch your storefront (as opposed to purely backend/admin apps) inject code into your theme in one of three ways:
- App embeds and app blocks, added via the theme editor’s App Embeds panel, these are the “sanctioned” way apps add functionality since Online Store 2.0. They still load JavaScript and CSS, just in a more structured, toggle-able way.
- Direct theme.liquid edits, older apps, or apps installed before Online Store 2.0 conventions became standard, sometimes ask you to manually paste a script snippet into
theme.liquid, usually just before the closing</head>or</body>tag. - ScriptTag API injections, apps can use Shopify’s ScriptTag API to add JavaScript to every storefront page programmatically, without it ever appearing in your visible theme code. This is the sneakiest source of bloat because you won’t find it by reading through
theme.liquidat all.
The problem isn’t that any single one of these is heavy. It’s cumulative. A reviews app, an upsell app, a currency converter, a live chat widget, a countdown timer, a trust badge app and a loyalty programme each add “only” 30-80KB of JS and a render-blocking style sheet, but stack six or seven of those on top of your theme’s own assets and you’ve got a page that’s shipping megabytes of code before the customer has scrolled an inch.
Each script also typically fires its own network request, and often a call back to the app’s own servers to fetch configuration or personalisation data. That’s where the real damage happens, not just download weight, but added round trips that delay when the page becomes interactive.
Step 1: Get a Baseline With Lighthouse and PageSpeed Insights
Before you touch a single app, get a clean baseline so you can measure whether your changes actually help.
- Open your store in an incognito/private window (so browser extensions don’t skew results).
- Run Google PageSpeed Insights (pagespeed.web.dev) against your homepage, a collection page and a product page, these behave differently because product pages often carry the heaviest app payload (reviews, upsells, size guides).
- In Chrome DevTools, open the Lighthouse tab, select Mobile, and run a report locally too. Local Lighthouse and PageSpeed Insights won’t match exactly (different server locations and throttling profiles), but the diagnostics detail, particularly “Reduce unused JavaScript” and “Eliminate render-blocking resources”, is what you actually care about, not the single headline score.
- Note your Largest Contentful Paint (LCP), Total Blocking Time (TBT) and the number of third-party scripts flagged in the “Reduce the impact of third-party code” section. This section is your shortlist, Lighthouse will name the actual domains (e.g.
cdn.judge.me,widget.klaviyo.com) chewing up main-thread time.
Save these reports. You’ll want a before/after comparison once you start removing or replacing apps.
Step 2: Read the Network Waterfall Properly
This is the step most people skip, and it’s the most revealing one.
- Open Chrome DevTools → Network tab.
- Set throttling to “Fast 3G” or “Slow 4G”, this exaggerates the impact of extra requests so bottlenecks are obvious, and it’s closer to real mobile conditions than your office wifi.
- Tick “Disable cache” and reload the page.
- Sort by Time or look at the waterfall chart itself. You’re looking for:
– Scripts loading from third-party domains you don’t recognise (right-click → Copy → Copy as cURL, or just note the domain and search it, most app JS files are served from a recognisable CDN subdomain likecdn.shopify.com/extensions/for app embeds, or the app’s own domain).
– Requests that block rendering, anything withoutasyncordeferthat loads before your visible content.
– Duplicate or near-duplicate requests, it’s common to find two different apps both loading their own copy of a library like jQuery or a font, because neither developer assumed the other was already present.
– Long “Waiting (TTFB)” bars on third-party requests, this means the app’s own server is slow to respond, and your storefront is waiting on it.
Filter the Network tab by “JS” and “CSS” to cut the noise, then click into each third-party request and check its Initiator column, this tells you which script or tag triggered the load, which usually points straight back to the app.
Step 3: Find What’s Injecting Code Into Your Theme
Now cross-reference what you saw in the network tab with your actual theme code.
Check app embeds and blocks:
Go to Online Store → Themes → Customize, then click App embeds in the left panel (bottom of the block list). This shows every app that’s registered a storefront embed, whether it’s toggled on or off. Toggle each one off individually, reload the storefront in another tab, and watch what disappears from the network waterfall. This is the single fastest way to isolate an app’s actual footprint.
Check theme.liquid and other templates directly:
In the theme editor, go to Edit code and open layout/theme.liquid. Search for:
– <script tags that reference a domain other than your own store or cdn.shopify.com
– HTML comments like <!-- BEGIN [App Name] -->, most apps politely (or not so politely) leave these markers
– Snippet includes such as {% render 'app-name-snippet' %}, check the snippets folder for files with obvious app-related names
Check for orphaned code from uninstalled apps:
This is the part people forget. When you uninstall a Shopify app, it does not always remove the code it added to theme.liquid, particularly for apps installed before Online Store 2.0 or ones that didn’t clean up properly. If you’ve uninstalled apps in the past, search your theme code for snippet files and script blocks that no longer correspond to anything in your Apps list. These are pure dead weight: no functionality, all cost.
Check ScriptTags via the API:
If you suspect an app is injecting scripts invisibly (common with older marketing pixels and some analytics apps), you’ll need to check the ScriptTag registrations, which don’t show up in the theme editor at all. This usually requires a developer to query it via the Shopify Admin API or a Shopify CLI app, worth flagging to a specialist if you’re not comfortable in the API.
Step 4: Build Your Audit Table
Once you’ve identified the apps loading code, put them in a simple table so the decision is visible, not just felt:
| App | KB loaded | Blocking? | Business function | Usage/impact evidence | Verdict |
|---|---|---|---|---|---|
| Reviews app | 140KB | No (async) | Product page trust | Reviews visible on 80% of PDPs, referenced in support tickets | Keep |
| Countdown timer | 60KB | Yes | Urgency on sale pages | Only used on 2 campaign pages/year | Remove, add manually when needed |
| Old currency converter | 95KB | Yes | Currency switching | Superseded by Shopify Markets | Remove |
For each app, capture: the file size it loads, whether it’s render-blocking, what business function it serves, and, critically, evidence of whether it’s actually being used (check the app’s own dashboard for click-through or conversion data, or ask the team who requested it whether it’s still needed).
The Keep / Replace / Remove Framework
Once you have that table, apply a simple decision framework to each row:
Keep, if the app is render-blocking-free (or minimal), demonstrably tied to revenue or a required business function, and there’s no lighter-weight native Shopify alternative.
Replace, if the function is genuinely needed but:
– Shopify now offers it natively (currency/market handling via Shopify Markets, basic form building, simple upsells via Shopify’s own Checkout and Cart APIs)
– a lighter competitor app exists that does the same job with a smaller footprint
– the app is duplicating something another app already does
Remove, if:
– nobody can explain why it’s still installed
– the feature is used on fewer than a handful of pages but loads on all of them
– it was for a one-off campaign that ended
– you find it’s an orphaned script left behind by an app you already uninstalled
A good rule of thumb from doing this repeatedly across different stores: any app that isn’t earning its keep on every page it loads on is a candidate for at minimum a “load only where needed” fix, even if you’re not ready to remove it outright, many apps let you restrict which templates they load on via their own settings or via conditional logic in the app embed.
When to Bring In a Specialist
Manually toggling app embeds and reading network waterfalls will get you most of the way, particularly for identifying obvious offenders. Where it gets harder is when scripts are loaded conditionally, when ScriptTag injections aren’t visible in the theme editor, or when removing an app risks breaking a checkout or subscription flow that depends on it.
If you want a second set of eyes, or you’d rather hand the whole audit and clean-up to someone who does this weekly rather than once a year, a Shopify audit covers exactly this: full performance profiling, app-by-app footprint analysis, and a prioritised action list you can hand to a developer or have actioned directly.
FAQ
How many apps is “too many” for a Shopify store?
There’s no fixed number, a lean 8-app store can be slower than a well-managed 20-app store if the wrong apps are installed. What matters is cumulative script weight and how many are render-blocking. As a general guide, if your Lighthouse report flags more than 4-5 third-party scripts materially affecting Total Blocking Time, it’s worth a proper audit.
Will removing an app automatically remove its code from my theme?
Not always. Well-built apps using the Online Store 2.0 app embed system clean up after themselves. Older apps, or ones installed via manual theme.liquid edits, often leave orphaned snippets and script tags behind. Always check theme.liquid and the snippets folder after uninstalling.
Does app bloat actually affect my Shopify SEO, or just page speed?
Both are connected. Page speed (specifically Core Web Vitals like LCP and interactivity metrics) is a confirmed Google ranking signal, and slow, janky pages also increase bounce rate, which indirectly hurts how search engines and ad platforms assess your site quality. If you’re auditing for speed, it’s worth pairing it with a broader look at Shopify SEO fundamentals at the same time.
Can I just disable an app instead of uninstalling it to test impact?
Yes, and this is the safest approach. Most apps let you pause or disable the storefront embed without fully uninstalling, which preserves your settings and data if you decide to reinstate it. Test disabling during low-traffic hours first.
Should I do this audit myself or get a developer involved?
The diagnostic steps, Lighthouse, network tab, toggling app embeds, are genuinely doable without a developer. Where you need technical help is fixing what you find: safely removing orphaned code from theme.liquid, restructuring how scripts load (async/defer, conditional loading by template), or replacing an app’s function with native Shopify code.
If you’ve been putting off a proper look under the hood, a book a call with our team is a low-pressure way to talk through what you’re seeing and whether it’s worth a full audit.