All posts
Performance · 6 min read · June 2026

Why your Shopify store is slow — and the five fixes that move the needle

Most store-speed advice is a checklist of forty things that each save four milliseconds. Here are the five that actually change what a customer feels, ranked by how much they matter on a real store.

EDIT · cover image

I get asked to "make the store faster" more than almost anything else, and nearly every time the merchant arrives with a Lighthouse score and a sense of dread. The score is rarely the problem. The problem is that a handful of decisions — usually made by people who never opened the codebase — are quietly costing the store its load time. Fix those, and the score follows. Chase the score directly, and you'll spend a week shaving milliseconds nobody will ever notice.

So before anything else: stop optimizing for the lab and start optimizing for the field.

Measure the thing customers actually feel

Lighthouse runs a simulated load on a simulated device. It's useful for catching regressions, but it is not how your customers experience the store. What you want is field data — real loads from real phones on real networks — and that comes down to three Core Web Vitals:

Pull these from the Chrome User Experience Report or your real-user monitoring, not from a one-off Lighthouse run. Once you're looking at field numbers, the five fixes below are almost always where the time is hiding.

1. Cut the app bloat (this is usually 60% of the problem)

This is the single biggest lever on most stores, and it has nothing to do with code you wrote. Every app you install can inject its own JavaScript and CSS into every page — review widgets, upsell popups, currency switchers, "someone in Ohio just bought this" notifications. Ten apps, ten extra render-blocking bundles, most of them loading on pages where they do nothing.

Audit what's actually running. Open the network tab on a product page and sort by size. You'll usually find two or three apps responsible for the bulk of the third-party weight, and at least one app you forgot you installed. Uninstalling cleanly (not just disabling) and removing orphaned script tags is often a bigger win than any code change.

The fastest line of JavaScript is the one you deleted.

2. Fix your images properly

Images are almost always the LCP element, and they're almost always shipped wrong. Three things matter:

And lazy-load everything below the fold — but never the LCP image. Lazy-loading your hero is a classic own-goal that delays the one paint you're trying to speed up.

<!-- Responsive, CDN-sized, space reserved, eager for the hero -->
<img
  src="{{ product.featured_image | image_url: width: 800 }}"
  srcset="{{ product.featured_image | image_url: width: 400 }} 400w,
          {{ product.featured_image | image_url: width: 800 }} 800w,
          {{ product.featured_image | image_url: width: 1200 }} 1200w"
  sizes="(max-width: 750px) 100vw, 50vw"
  width="1200" height="1500"
  loading="eager" fetchpriority="high"
  alt="{{ product.featured_image.alt | escape }}">

3. Tame third-party scripts

Analytics, chat widgets, pixels, A/B testing tools — none of them should block your page from rendering. The fixes are unglamorous but reliable: load them with defer or async, push anything non-essential to load after first interaction, and move checkout-page tracking into Shopify's Web Pixels sandbox rather than injecting it inline.

That last point isn't optional anymore. Since the move to Checkout Extensibility, the old habit of pasting tracking snippets into Additional Scripts is gone — and the sandboxed pixel approach is both the supported path and the faster one. If your store is still leaning on legacy script injection, you have a performance problem and a deprecation problem in the same place.

4. Stop blocking the first render

Render-blocking resources are CSS and JS the browser must finish before it can paint. On a typical theme the culprits are a giant global stylesheet, a web-font that loads invisibly, and a blob of theme JavaScript at the top of the page.

5. Respect the Liquid in your loops

This is the one that's actually your code, and it's where a fast theme quietly turns slow as the catalog grows. The usual offenders are loops that do too much work per iteration and pages that render the entire collection instead of paginating.

None of this shows up on a small dev store with twelve products. All of it shows up on the real one with twelve thousand.

When speed becomes an architecture question

Do these five things well and the vast majority of stores land in the green without touching the platform. A small number won't — stores with genuinely complex, app-like front ends where you're fighting the theme on every page. That's the point where headless stops being hype and starts being a real option, and it deserves its own honest conversation, which I get into over here.

The short version

  • Measure field Core Web Vitals (LCP, INP, CLS), not Lighthouse scores.
  • App bloat is usually the biggest single cost — audit and uninstall ruthlessly.
  • Right-size images, reserve their space, and never lazy-load the hero.
  • Defer third-party scripts; move checkout tracking into Web Pixels.
  • Keep your Liquid loops lean and paginate large collections.
PerformanceCore Web VitalsLiquidCheckout Extensibility
YN
Your Name

Shopify developer and ex–Silicon Valley engineer (NVIDIA, Apple). I build fast, custom storefronts and apps for brands that have outgrown the theme store. Get in touch →