Shopify site speed: a real audit, and real fixes
A Shopify site speed audit: what the admin report actually measures, which app and theme fixes pay off, and what the platform locks away.
In this article
Two speed reports for the same store, on the same day, disagreeing. Neither one is broken. Shopify’s web performance report in the admin combines data from your home page, most visited product page, and most visited collection page from the last 7 days, gathered from visitors on Chromium-based browsers and Firefox. Search Console pulls from CrUX, which only measures Chrome, and only the subset of users who opted in to share that data when the browser was installed. Different populations, different windows, different numbers.
Most speed audits that land on my desk started in the wrong place. Someone saw an ugly number in the admin, panicked, and the store has spent two months installing optimisation apps to push it up. I work the other way round: decide which number rules, find what’s breaking it, and I nearly always end up in the same place, which is the code apps have left behind inside the theme. This is that audit, with a clear line between what you can change and what the platform decides for you.
In 30 seconds:
- The admin report and the Search Console report sample different browser populations, so they won’t line up.
- Google judges you on CrUX field data over a rolling 28-day window, not on a lab score.
- Uninstalling an app doesn’t remove its code from your theme. That’s Shopify’s own documentation, not my opinion.
- A good LCP is 2.5 seconds and a good INP is 200 milliseconds, both at the 75th percentile.
- You win time by removing scripts, not by adding tools.
Is the Shopify admin speed score worth optimising for?
It’s a smoke alarm, not a target. The performance score in the admin is built on real data: Shopify explains that the system uses real user data, called Real User Metrics or RUM, from visitors using Chromium-based browsers and Firefox. That beats a simulation by a wide margin. The problem sits elsewhere.
That dataset isn’t the one Google looks at. Search Console states plainly that the data for the Core Web Vitals report comes from the CrUX report, which gathers anonymized metrics about performance times from actual users visiting your URL, called field data. CrUX means Chrome, opted in, over 28 days. The admin adds Firefox, Edge, Opera and Samsung Internet, and squeezes the window down to 7.
So is the admin report useless? Not at all, and I check it weekly. With a 7-day window you catch a Tuesday regression from something you installed on Monday, which CrUX won’t tell you about for a long while yet. What you can’t do is chase that figure as if it were your grade from Google. It isn’t. If you’re starting from zero on the metrics themselves, my guide to Core Web Vitals on Shopify covers what each one measures.
Which data source should drive which decision?
My rule is short: CrUX decides whether you have a problem, the lab decides what it is. Lab tools don’t tell the truth about your users, but they’re the only ones that hand you a resource waterfall with names and file sizes. Field data tells the truth and never explains itself.
| Source | What it is | Who’s in the sample | Window | What I use it for |
|---|---|---|---|---|
| Admin web performance report | Field (RUM) | Chromium and Firefox | 7 days | Catching regressions fast |
| Search Console Core Web Vitals | Field (CrUX) | Chrome, opted in | 28 days | Seeing how Google grades you |
| PageSpeed Insights, field block | Field (CrUX) | Chrome, opted in | 28 days | Checking one template |
| Lighthouse or PSI, lab block | Lab | Nobody real | Instant | Naming the guilty resource |
The thresholds are identical across every source. Google says LCP should occur within 2.5 seconds of when the page first starts loading, that pages should have an INP of 200 milliseconds or less, and that all of it is measured at the 75th percentile of page loads, split between mobile and desktop. The 75th percentile means your median visitor doesn’t count. The one having a bad time does.
Why are apps the biggest speed cost on a Shopify store?
Because their code outlives the uninstall. Shopify says it without hedging: uninstalling an app doesn’t automatically remove its code from your theme, and the same page asks you to evaluate your installed apps and third-party code to make sure they create enough value to offset any potential performance losses.
Translated into what I actually find on a three-year-old store: the script for a size finder that was dropped in 2024, two review widgets because someone switched providers without cleaning up, and a tag manager carrying pixels from the previous agency. None of that shows up in the apps list. All of it runs on every page load.
Shopify’s theme documentation is just as blunt about the mechanism. It tells you to identify and remove or defer app scripts that block HTML parsing before any content is rendered, and to audit everything that loads, stripping out whatever isn’t earning its performance cost. That “isn’t earning it” is the hard part, because every app has someone inside the company defending it.
To untangle it I duplicate the theme, pull one block at a time, and measure. Never all of them at once. It’s slow and it’s the only way to attribute the saving. If you’re also dragging template problems around, my rundown of common Shopify SEO mistakes overlaps with this list more than you’d expect.
Which theme problems can you actually fix yourself?
The ones affecting how the main image is discovered and painted, which on a product page is usually the LCP element. Shopify’s rules here are specific, and you don’t need to be a developer to apply them.
- Never lazy-load the LCP image. Shopify warns that
loading="lazy"on the LCP image delays it until after layout completes. It’s the most expensive mistake and the easiest to make, because the setting usually gets applied across the whole theme in one go. - Use
<img>instead of CSS background images for hero content, so the browser’s preload scanner can find it early. - Apply
fetchpriority="high"to the LCP image to signal its importance before the browser completes layout. - Always include
widthandheight, or useimage_tag, which adds them for you, and build URLs withimage_urlrather than assembling CDN URLs by hand.
Then come the render blockers. The same page notes that render-blocking stylesheets and scripts in the <head> are the usual reason LCP arrives late, and advises loading critical CSS for the initial viewport synchronously. It isn’t about deferring everything. It’s about deciding what belongs in the first screen.
And then there’s Liquid, where the server time hides. Shopify asks you to eliminate O(n²) patterns, including nested loops and metafield access inside loops, that make rendering time grow quadratically, and to keep pagination under 25,000 objects. On a large collection, one badly placed nested loop weighs more than all your images put together. For the code itself I’ve written about Liquid for SEO and image optimisation on Shopify.
What order do I run the audit in?
Always the same one, and always measuring before touching anything. The sequence isn’t decorative: each step rules out hypotheses for the next, and skipping ahead gets you optimising something that was never the problem.
- Record the starting state in both field sources. Admin and Search Console, same day, screenshots included. Without a baseline you don’t have an audit, you have opinions.
- Split by template. Home, collection and product pages have different problems and rarely share a culprit. Bad LCP on product pages only points at the gallery.
- Identify the real LCP element on the worst template, using the browser’s performance tab. Don’t assume. On half a dozen stores it wasn’t the image everyone took for granted.
- List everything that runs before that paint: scripts in the
<head>, app embed blocks, tag manager containers, custom fonts. - Cross-reference that list against installed apps. Anything running that maps to no active app is leftover from an uninstall, and it’s the best effort-to-result work in the whole audit.
- Duplicate the theme and remove one element at a time, measuring in the lab after each change.
- Check the image rules: no lazy loading on the hero,
fetchpriorityon the LCP image, dimensions declared,image_urleverywhere. - Hunt for nested loops and metafield access inside loops in any section rendering long lists.
- Ship it and wait. CrUX moves on a 28-day window, so confirmation isn’t arriving in 48 hours however much you want it to.
Step 9 is the one nobody handles well. The work gets done, someone opens Search Console the next morning, nothing has moved, and the conclusion is that it didn’t help. That’s exactly what the admin report is for.
What are you never going to fix?
More than you’d like, and knowing it saves weeks. Liquid rendering happens on Shopify’s servers, your images are delivered by their CDN, and checkout doesn’t live inside your theme. You can write cheaper Liquid. You can’t change where it runs. That advice about keeping pagination under 25,000 objects is a platform limit dressed up as a best practice.
There are also scripts you won’t be allowed to remove for reasons that aren’t technical: the pixel for a channel the client invoices against, the accessibility tool legal insists on, the chat widget support uses daily. What’s left there is negotiating when they load rather than whether they load, by getting them off the critical path to first paint.
My bar for closing an audit is this: if LCP sits under the threshold on the templates that make money, and INP doesn’t spike when someone opens the variant picker, I’m done. Chasing tenths beyond that pays better elsewhere, usually in the mobile buying experience, which is a conversion problem rather than a milliseconds problem. I handle that separately in mobile CRO for ecommerce.
Frequently asked questions
Why doesn’t my Shopify admin score match PageSpeed Insights?
Because they aren’t measuring the same thing. The admin uses real data from Chromium-based browsers and Firefox over the last 7 days. The field block in PageSpeed Insights uses CrUX, which covers Chrome only and only users who opted in, over a 28-day window. With different samples and different periods, an exact match would be the suspicious outcome.
What Core Web Vitals thresholds do I need to hit?
LCP within 2.5 seconds, INP of 200 milliseconds or less, and CLS below 0.1. All of it is judged at the 75th percentile of page loads, split between mobile and desktop. Shopify frames the same idea in practical terms: at least 75% of your page loads need Good scores across all three metrics for a search engine to call your performance good.
Are Shopify App Store speed optimisation apps worth it?
It depends on what’s underneath, but my default answer is don’t start there. One more app is one more script running on every load, and that’s usually the exact problem you’re trying to solve. Clean out the residue from old apps first and fix the image rules. If there’s still headroom after that, then go and evaluate tools.
How long before a speed improvement shows up?
In the lab, immediately. In Search Console, weeks, because CrUX works on a rolling 28-day window and needs to accumulate enough fresh page loads. The admin report, with its 7 days, confirms you’re heading the right way first. Don’t make decisions off a single day of data in either source.
Does a paid theme solve the speed problem?
Not always, and in most cases it only fixes the starting point. A well-built theme gives you a better launch, but the decay comes later, with the apps, the pixels and the sections piling up over two years. I’ve seen paid themes with worse LCP than clean free ones. Maintenance matters more than the purchase.
Speed is won by removing things
After a decent number of audits, my conclusion is unglamorous: nearly all the recoverable time was already sitting inside the store, as code someone installed and nobody ever took out. There’s no advanced technique involved. There’s an inventory, some patience, and the willingness to argue with whoever is defending an app nobody has used in a year.
The other thing I learned the hard way: don’t optimise against a number that isn’t the one grading you. The admin report is a good smoke detector because it reacts in days. Search Console reflects what Google sees, with its Chrome sample and its 28 days. Confusing the two leads to celebrating improvements that never happened. If the rest of the technical work is still pending, my Shopify SEO guide sets the order to tackle it in.
If you want me to look at your store and tell you what can come out without breaking anything, book 30 minutes of consulting.
Could your ad campaigns
perform better?
30 minutes to review your situation and tell you exactly what I would change. No pitch, no sales proposal.