
Shopify Speed Optimization in 2025: From Slow to Selling Fast
Problem (Slow store, low conversion)
Why speed = revenue on Shopify
Speed shapes first impressions, search visibility, and checkout completion. Shoppers form an opinion in seconds; if your store hesitates or shifts around, users bounce and don’t come back. Google’s ranking systems increasingly factor real-world speed and stability, so a slow store can struggle to win traffic and then wastes the traffic it gets.
The three Core Web Vitals, explained simply
-
LCP (Largest Contentful Paint): how fast the main content (usually your hero image or product image) becomes visible.
Good: ≤ 2.5s at the 75th percentile (p75) for both mobile and desktop. -
INP (Interaction to Next Paint): how quickly your store responds to taps/clicks and visibly updates the UI.
Good: ≤ 200ms at p75. -
CLS (Cumulative Layout Shift): how stable the page is while loading (no jumps).
Good: ≤ 0.1 at p75.
Field data vs. lab data (how to read results)
- Field data (CrUX, Shopify’s Web Performance dashboard): real users on real devices and networks. This is what Google evaluates for rankings.
- Lab data (PageSpeed Insights/Lighthouse): controlled tests on a standard device/network. Crucial for debugging and verifying your fixes before they show up in field data.
Typical Shopify bottlenecks (what we find most)
On Shopify, the most common slowdowns come from too much JavaScript loaded on every page, especially from multipurpose apps and tag managers, which drags down interactivity (INP). Oversized hero and product images routinely push LCP beyond “Good.” Blocking fonts and third-party widgets delay the first paint, and category pages (PLPs) with long product lists or product pages (PDPs) with heavy review widgets slow the experience when it matters most.
How to self-diagnose in 10 minutes
Start with Shopify’s Web Performance dashboard to see which templates fall short at p75. Open Google Search Console → Core Web Vitals to review URL groups across mobile and desktop. Then run PageSpeed Insights on key templates; use the Diagnostics and Treemap panels to locate heavy scripts, images, and long tasks. Those three views together tell you where to focus first.
Suggested image under this section: upload shopify-core-web-vitals-lcp-inp-cls-2025.svg
with alt text “Core Web Vitals targets (LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1) for Shopify at p75.” It’s a lightweight SVG tile with clear LCP/INP/CLS badges.
Process (Tools & Techniques)
This is the exact workflow we apply to Shopify Plus builds and retrofits. The theme: keep the main thread light, keep the hero fast, and only load what a template truly needs.
1) Theme & code hygiene — your performance foundation
We begin by updating the base theme and removing sections, snippets, and assets that no longer serve the design. Non-critical JavaScript is deferred or split so above-the-fold content can paint immediately, and we inline only the critical CSS needed for the first viewport while deferring the rest. In Liquid, we keep above-the-fold code lean and cache repeated queries in shared snippets. Inside theme.liquid
, non-critical scripts move to the bottom or load with defer
; giant global bundles are broken into smaller, route-aware chunks that load only where used. A quick Lighthouse Treemap pass confirms that weight moved off the initial render path. Throughout, we watch for render-blocking assets, duplicated libraries, and main-thread long tasks (anything over ~200ms).
.How to implement in Shopify
- In
theme.liquid
, move non-critical scripts to the bottom or usedefer
. - Convert giant “global” files into smaller, route-aware chunks loaded only where used.
- Run Lighthouse → Treemap to confirm reductions.
What to watch
- Long tasks > 200ms, render-blocking CSS/JS, duplicate libraries.
2) App diet — the fastest app is often the one you remove
Next, we run an app audit. Unused apps are uninstalled; multi-tool apps are replaced with lighter, single-purpose alternatives. Wherever possible, we switch from “load on every page” to template-level loading via App Embeds or theme app extensions, so scripts appear only where they’re needed. Analytics and marketing tags are scheduled after first paint or on interaction when appropriate. This discipline is one of the most reliable ways to protect INP, because it directly reduces JavaScript on the main thread.
How to implement in Shopify
- Use App embeds and theme app extensions so you can toggle per template.
- For analytics/marketing tags, load after first paint or on interaction if possible.
What to watch
- Heavy third-party JS is a common root cause of poor INP.
3) Images & media — the biggest, easiest wins
Hero and product media move to WebP/AVIF with aggressive but safe compression. We serve responsive images via srcset/sizes
so devices download only what they need, and we lazy-load everything that isn’t critical. Crucially, we preload only the LCP image, usually the hero or primary product image—so the network prioritizes what the user sees first. In the Customizer, we set focal points and size presets, and we rely on components that emit responsive markup automatically.
How to implement in Shopify
- In the Customizer, set focal points and size presets.
- Use image components/filters that emit
srcset/sizes
. - Add a single
<link rel="preload" as="image">
for the hero on that template only.
4) Fonts — free speed without design compromise
Fonts are hosted on the same origin when possible; the first text-paint font is preloaded, and font-display: swap
ensures copy appears immediately. We limit families and weights (or use a variable font) and, where brand allows, use a system UI font for interface chrome while reserving brand typography for headings. The result is crisp design without blocking the render.
How to implement in Shopify
- Add
<link rel="preload" as="font" ... crossorigin>
intheme.liquid
. - Remove unused font files; rely on system UI font for UI chrome if brand allows.
5) PLP & PDP specifics — where most revenue lives
PLP (collection)
- Reduce per-page product counts (or virtualize long lists).
- Defer quick-add and filter JS until interaction.
- Ensure list/item images are compressed and properly sized.
PDP (product)
- Make the above-the-fold product image your LCP candidate.
- Lazy-load thumbnails, below-the-fold content, and defer reviews until scroll/interaction.
- Keep “You may also like” carousels off the initial render path.
Process map (row & column table)
Area | Technique | Where in Shopify | Main Metric Impact | Tooling |
---|---|---|---|---|
Theme JS/CSS | Defer non-critical JS, inline critical CSS |
theme.liquid , sections/*.liquid
|
INP, LCP | PSI/Lighthouse, Shopify Web Performance |
Apps | Remove unused, load scripts on demand | App embeds, theme app extensions | INP | Lighthouse Treemap, Chrome Profiler |
Images | WebP/AVIF, srcset/sizes , lazy-load |
Sections: hero, product media | LCP | PSI, Network panel |
Fonts | Preload first font, swap, trim weights |
theme.liquid head, assets/
|
LCP | PSI, Coverage |
PLP/PDP | Limit PLP items; defer reviews on PDP |
collection.* , product.*
|
LCP, INP | PSI field + lab checks |
Results (Measurable numbers)
Below are the OptiExperts PageSpeed Insights results (from our audited homepage on Aug 1, 2025). These demonstrate the standard we aim to maintain across Shopify themes and Plus builds.
Score overview (row & column table)
Device | Performance | Accessibility | Best Practices | SEO |
---|---|---|---|---|
Desktop | 98 | 93 | 96 | 92 |
Mobile | 98 | 92 | 96 |

Core metrics (lab) — what users feel
Device | First Contentful Paint (FCP) | Largest Contentful Paint (LCP) | Total Blocking Time (TBT) | Speed Index | Cumulative Layout Shift (CLS) |
---|---|---|---|---|---|
Desktop | 0.5s | 1.0s | 70ms | 0.7s | 0.00 |
Mobile | 1.1s | 2.4s | 50ms | 1.1s | 0.00 |

What these numbers say (deep dive)
An LCP of 1.0s on desktop and 2.4s on mobile sits well inside the “Good” threshold, which means users see the key content almost immediately and are less likely to bounce. TBT at 70ms/50ms tells us the main thread stays clear of heavy blocking tasks, which generally correlates with healthy INP in the field. And CLS at 0.00 confirms there are no unexpected layout jumps, so users can tap confidently without misclicking.
How we maintain these results over time
- Performance gates: we ship only if PSI mobile stays ≥ 90 and LCP ≤ 2.5s at p75 in field data.
- App governance: any new app must load by template and pass a JS budget check.
- Content standards: editors upload WebP/AVIF, follow size presets, and never preload non-hero images.
How we keep performance high over time
We ship behind performance gates: PSI mobile must remain ≥ 90 and LCP ≤ 2.5s at p75 in field data before release. Any new app is evaluated against a JavaScript budget and must load by template, not globally. Content editors follow an image and font standard—WebP/AVIF only, responsive sizes, no preloading of non-hero images—so routine updates don’t erode speed.
Let’s optimize your store