Quick answer: on most Shopify stores the speed problem is apps and images, in that order, and the fix is removal and compression rather than clever engineering. Ignore the admin speed score; measure Largest Contentful Paint, Interaction to Next Paint and Cumulative Layout Shift from real visitors, because those are what Google uses and what correlates with conversion.

Measure the right three numbers

Shopify's admin shows a speed score. It is a Lighthouse lab score — a simulated load on a simulated device — and it moves for reasons that have nothing to do with your visitors. Useful for comparing your store to itself last month; not what Google uses.

Google uses field data: what actually happened to real people on real connections.

Metric Measures Pass Usual Shopify culprit
LCP When the main image or heading is painted < 2.5s Hero image lazy-loaded, uncompressed, or behind a slider
INP How fast the page responds to a tap < 200ms App JavaScript executing on the main thread
CLS How much the layout jumps < 0.1 Images without dimensions, banners injected late, fonts swapping

Search Console's Core Web Vitals report shows these from your own visitors. PageSpeed Insights shows both field and lab data for a URL — read the field section first and treat the lab section as a diagnosis of why.

Apps are usually the biggest single line

Every app that injects a script adds bytes to download, parse and execute, and it does so on every page whether that page uses the app or not. Twelve apps is not twelve small costs; it is twelve competing for the same main thread.

Audit properly:

  1. List every installed app and write down what each one earns you. Anything you cannot answer for is a candidate.
  2. Uninstall the candidates.
  3. Then check the theme for leftovers. This is the step people skip. Uninstalling an app does not always remove the script tag it added to theme.liquid, so you can be paying the load cost of an app you no longer have. Search the theme for the app's name and CDN domain.
  4. Re-measure after each removal, not at the end, so you know which one mattered.

The Googlebot simulator shows the raw HTML a crawler receives, which is a quick way to see how much of your page is third-party script before anything renders.

Images: compress, size, and stop lazy-loading the hero

Images are usually the largest bytes on a Shopify page and the easiest thing to halve.

Shopify's CDN already does more than most merchants realise. It serves WebP automatically to browsers that accept it, and it resizes on request through URL parameters. What it cannot do is undo a 4 MB original — it will serve a smaller format, not a smaller photograph. Compress before upload.

Size the request to the slot. A 2,400px image displayed in a 600px column wastes three quarters of its bytes. Shopify's image URLs accept ?width= — use it, and provide a srcset so phones do not download desktop images.

The hero is the exception to every lazy-loading rule. It is almost always the LCP element, so lazy-loading it defers the one image Google is timing. Set it loading="eager" and fetchpriority="high", and lazy-load everything below the fold. Stores that "add lazy loading everywhere" and get slower have almost always done exactly this.

Always set width and height. Without them the browser cannot reserve space, the page reflows when the image arrives, and that is CLS. Image SEO on Shopify covers the alt-text and filename side; this is purely the performance side.

Fonts, and the invisible cost

Custom fonts are a real cost paid on every first visit. Three rules cover most of it:

  • Ship fewer. Two families and two weights each is plenty. Four families is a design decision with a performance price tag.
  • font-display: swap. Otherwise text is invisible while the font loads — a blank page that feels broken even when it is fast.
  • Preconnect to the font host. One line in theme.liquid that saves a DNS lookup and TLS handshake on the critical path.

Shopify's own font library is served from the same origin as the storefront, which removes the connection cost entirely. Worth considering if your brand font is not load-bearing.

What you cannot fix, and should stop trying to

Shopify controls the server response time, the CDN, the checkout and the core platform JavaScript. You cannot tune any of it, and a meaningful portion of any Lighthouse report will be things in that category.

This matters for expectation-setting: there is a floor, it is the same floor for every store on the platform, and a "speed optimization service" promising to break it is selling something else. What is genuinely yours is everything after the HTML arrives — and on an app-heavy store, that is where nearly all of the avoidable loss lives.

An ordered plan

Week 1 — measure and remove. Record LCP, INP and CLS from Search Console. Audit apps, uninstall the unjustifiable ones, search the theme for leftover scripts. Re-measure.

Week 2 — images. Compress and re-upload the heroes on your homepage and top collections. Add explicit width and height. Fix the hero's loading attribute. Reduce slider images to what is actually seen.

Week 3 — fonts and third parties. Cut font families and weights. Add preconnect. Defer any remaining third-party script that is not needed for first paint.

Week 4 — re-measure and stop. Field data lags by up to 28 days, so do not judge week 1 in week 2. When the three numbers pass, stop: further optimisation on a passing store is effort that would earn more elsewhere.

Where speed sits against everything else

Speed is a tiebreaker. A fast page that answers the query badly still loses to a slow page that answers it well — which is why "improve Core Web Vitals" is rarely the highest-value item on a store with 2,000 products and no meta descriptions.

Fix it because visitors abandon slow stores and because it is a real ranking input, but sequence it honestly. The Shopify SEO checklist puts it in order against the rest, and the free audit will tell you whether speed is genuinely your binding constraint or just the most visible thing to work on.