What "slow" really means
When a store owner tells me their store is slow, they usually mean one of three things. Google measures each of them separately, and each one has a different cause.
- LCP, Largest Contentful Paint. How long until the main thing on the screen, usually the hero image or the product photo, is visible. Google calls it good at 2.5 seconds or less.
- INP, Interaction to Next Paint. How quickly the page reacts when someone taps a button, opens the menu or picks a variant. Good is 200 milliseconds or less.
- CLS, Cumulative Layout Shift. How much the page moves around while it loads. Good is 0.1 or less.
These three are the Core Web Vitals. The part most owners miss is that there are two kinds of data for them.
Field data vs lab data
Field data comes from real visitors using Chrome on their own phones and connections, gathered over several weeks. It's the box at the top of PageSpeed Insights, when your store has enough traffic. Lab data is the score below it: one test, run once, on a simulated mid-range phone with a slow connection.
The lab test is useful for finding causes. It is a poor judge of whether you have a problem. On a UK book retailer I worked on, the lab test was still flagging layout shift while real visitors already passed all three: LCP 1.9 seconds, CLS 0.02 and INP 172 milliseconds. On a store in Pakistan, the lab test reported a mobile LCP of 8 seconds while the same page in a real Chrome loaded its hero in about 1 second.
Why the score swings from run to run
On a Saudi store I ran PageSpeed three times on the same page and got 40, 67 and 49. Nothing changed in between. What moved was Total Blocking Time, the time the phone's processor is busy running JavaScript. When a score jumps around like that, it's almost always telling you the page runs too much script, and the scripts finish at slightly different moments on every run.
A score that changes every run is not noise to ignore. It's the scripts talking.
The usual causes, ranked
This is the order I find them in on real stores, most common and most costly first.
1. Third-party JavaScript: apps, tag managers and duplicate tags
Shopify's own guidance says poor INP is often caused by too much JavaScript from theme code, apps, third-party code or tag managers. That matches what I see. Every review widget, popup, chat bubble, upsell and tracking pixel adds script that the visitor's phone has to download and run, often on every page.
The worst version is the same tag loaded twice. On that Saudi store, Google's tag script loaded six times: three Google tag IDs, each added once by the Google & YouTube app and again through Google Tag Manager. A Facebook pixel loaded twice too, plus Clarity, Hotjar through Tag Manager and a forms app popup. None of it was broken. It had just been added by different people at different times.
The fix is a decision, not code
Keep each ID once and load it from one place: either the app or Tag Manager, never both. That's a choice for whoever runs your marketing, because they know which reports depend on which tag. The code change after that takes minutes.
2. The hero image is found late, or the preload points at the wrong image
The browser can only start downloading the hero once it knows about it. A preload tag tells it early. When the preload is missing, or points at a different image, the hero waits its turn behind everything else.
On a book retailer in Pakistan, the homepage preload pointed at an image on another store's domain. The browser downloaded an image it never showed. On top of that, a hidden 1-pixel image marked as high priority, a trick often added to game the score, was taking bandwidth from the real hero.
3. CSS that arrives late and moves the page
On the same store, a stylesheet loaded near the bottom of the page. Until it arrived, the hero rendered at 600 pixels tall; then it snapped to 454. That jump alone gave a layout shift of 0.07 to 0.16 depending on the run, above Google's 0.1 line.
The same thing happens with JavaScript. On a UK store, a product carousel only got its mobile layout after a script ran, so the whole row shifted. Applying that layout in CSS from the first paint took CLS from 0.114 to 0.015.
Don't make every stylesheet non-blocking
A common speed tip is to load all CSS without blocking the page. On a slow connection that can show visitors a page with no styling for a moment, which looks broken. On two stores I deliberately made the main stylesheet blocking again, so the page is always styled when it appears. Small extra CSS can wait; the main stylesheet should not.
4. Font files nobody uses
On a UK book retailer's homepage, the theme loaded ten weights of one display font when the design used two. It also preloaded Shopify fonts the store had already replaced, and held the whole page until the font file arrived. Cutting it to two files on first load, removing the wasted preloads and letting the font stylesheet load without blocking made the first screen appear sooner. On the Pakistan store, the fonts were TTF files, which are larger than they need to be; switching to WOFF2 made them smaller without changing how they look.
5. A very heavy header
Mega menus are useful, but every link and image in them is part of the HTML of every page, and it sits before your content. A menu with hundreds of links makes every page larger before the visitor sees anything.
6. App embeds loading on pages that don't use them
A size chart app only matters on product pages. A store locator only on one page. Many apps still load their script on the homepage, collections and blog too, because that's the simplest way for the app to work everywhere. You pay for it on pages where it does nothing.
Where to look first
Tell me what you're seeing and I'll point you at the three most likely causes, using the patterns above.
What feels slow? Pick all that apply.
Apps that show something on your storefront
Google tags added by an app and by Tag Manager?
Changed the theme's fonts, or added custom ones?
A big mega menu with many links or images?
Look here first
Tell me what you're seeing.
Pick a symptom or answer a question, and the three places most likely to be slowing your store appear here.
A starting point from the patterns I see most, not a diagnosis. Real-visitor data and a look at the page source will confirm it.
Find yours in 15 minutes
You don't need tools beyond a browser. Do these in order.
- Read the field data. Run your homepage and one product page in PageSpeed Insights. Look at the real-visitor box at the top first. If LCP, INP and CLS all pass there, you don't have an emergency, whatever the score says.
- Run the lab test three times. If the score moves a lot between runs, note Total Blocking Time. A big, changing number means scripts.
- Count your tags. Open the page source and search for
gtag/js,googletagmanagerandfbevents. The same ID appearing twice is a duplicate. - List your app embeds. Theme editor → App embeds. Anything switched on for an app you no longer use is free speed.
- Check the hero preload. In the page source, search for
rel="preload". The image it names should be your actual hero, on your own store's domain. - Count font files. DevTools → Network → filter by Font, then reload. More files than your design has weights is waste.
- Watch the first screen. In DevTools, set the network to a slow 4G speed and reload. If anything changes size or jumps after it appears, that's your layout shift.
What you can fix yourself, and what needs a developer
Usually yourself: uninstalling apps you don't use, switching off their app embeds, deciding which marketing tags to keep with whoever runs your ads, and resizing very large images before uploading.
Usually a developer: changing preloads, where stylesheets load, font loading and the header's HTML. These are theme code changes, and a small mistake can make the store look broken. I always make them on a copy of the theme first, check it, then apply them to the live theme with a way to undo each one.
Tick what you found in the checklist above.
Start with apps and tags.
Nothing theme-level showed up. Remove unused apps, keep each tag once, then test again.
Notes from real stores
Three of these are from one multi-store book retailer, which is a good reminder that the same theme can be slow for different reasons on each store.
Book retailer · Pakistan
Wrong preload, a hidden image hack and late CSS
Fixed the hero preload, removed the 1-pixel trick, moved the stylesheet, switched fonts to WOFF2 and let below-the-fold sections render later. PageSpeed mobile LCP 12.9s → 8.0s and CLS → 0; desktop score 74 → 89, LCP 2.9s → 2.1s, CLS 0.157 → 0.01.
See how I work on speedBook retailer · UK
The homepage was downloading fonts it never used
Ten weights of one font cut to the two the design uses, wasted preloads removed and the font stylesheet no longer blocking the page.
Read the case fileBook retailer · Saudi Arabia
Google's tag loaded six times on one page
A score swinging between 40 and 67 on identical runs, traced to duplicate tags from an app and Tag Manager. The fix was choosing one place to load each ID.
Browse the Problem ClinicStore revamp
Mobile PageSpeed from 39 to 90
The same order as this article: remove what isn't needed, then make what's left load in the right order.
Speed optimisation serviceOne honest note on numbers: lab mobile runs on these stores varied by around 10 points either way, which is why I report the field data and repeated runs, never a single best score. And if your apps are part of the problem, it's worth asking whether you need them at all; I've written about when a custom app beats a stack of monthly ones.
Questions
Why does my PageSpeed score change every time I run it?
The mobile test simulates a mid-range phone on a slow connection, and small timing differences in JavaScript change the result. On one store I ran the same page three times and got 40, 67 and 49. The swing followed Total Blocking Time, which is JavaScript work, so a score that jumps around usually points at scripts.
Does the PageSpeed score affect my Google ranking?
The score itself is a lab test. What Google looks at is Core Web Vitals from real Chrome visitors, shown as field data at the top of PageSpeed Insights when your store has enough traffic. A store can show a weak lab score while its real visitors already pass, so read the field data first.
Will uninstalling apps make my store faster?
Often, yes, if the app loaded scripts on your storefront. But uninstalling doesn't always clean up. Some apps leave snippets in the theme or an app embed switched on, so check the theme code and the app embeds list after you remove one.
Can a speed optimisation app fix this for me?
It can delay or compress some files, but it adds a script of its own and it can't decide which of your marketing tags is the duplicate or which app you no longer need. Those are decisions about your business, and they're usually where the biggest gains are.
Do I need a new theme to fix speed?
Rarely. Every fix in this article was made inside the existing theme: fewer font files, a correct hero preload, CSS that loads in the right place and fewer duplicate tags. A new theme carries over the same apps and tags, so the same problems come back.
Send me your store link.
I'll check your field data, tags, app embeds, preloads and fonts, and tell you what's slowing it down and what's worth fixing.