crumpled paper texture
Back to Shopify Articles
ShopifyNovember 3, 2026(Updated: Nov 3, 2026)14 min read

Shopify Store Speed Optimization: A Practical Guide for Developers

A practical guide to making Shopify stores faster: measuring real pages, fixing oversized images, auditing apps, scoping theme code, and handling fonts, videos, and third-party scripts.

Yash Nandvana

Yash Nandvana

Full Stack Developer

Shopify Store Speed Optimization Architecture Diagram

Introduction

A slow Shopify store does not announce itself with an error message. It just quietly loses visitors. Someone clicks a product link, the page takes a few seconds to become usable, and they leave before they ever see the price. No crash, no bug report — just a sale that never happened.

Speed is not a vanity metric for a store. It affects how a page feels, how search engines judge it, and whether a visitor trusts the store enough to check out. The good news is that most Shopify speed problems come from a small set of causes: oversized images, too many apps, unscoped code, and pages that load everything at once whether the visitor needs it or not.

This guide covers how to find what is actually slow, and how to fix it in order of impact. It is written for developers working on Online Store 2.0 themes, but the principles apply to any Shopify store. It does not promise a specific score — scores vary by device, network, and page — it gives you a repeatable process that makes real pages measurably faster.

1. Measure Before You Optimise

Optimising without measuring is guessing. Before changing anything, record a baseline for the pages that matter most: the homepage, a collection page, and a product page. Those three pages cover most of a store's traffic, and they usually have different problems.

Useful, free ways to measure:

Shopify's own speed report in the admin, under Online Store, gives a comparative view of the store's speed and flags the biggest contributors.
PageSpeed Insights / Lighthouse gives a lab score plus field data where available, and — more usefully — a list of specific opportunities, with estimated savings for each.
A real phone on a real mobile network, or throttled network in browser developer tools, tells you what a visitor actually experiences. A page that feels fast on a developer's laptop on Wi-Fi can feel very different on a mid-range phone on mobile data.

Record three numbers for each key page: the time to first contentful paint, the time to largest contentful paint, and the total page weight. Write them down. After each fix, measure again. If a change does not move one of those numbers, it was not an optimisation — it was activity.

One warning about scores: a perfect lab score on a page with no products, no images, and no apps proves nothing. Optimise the real pages, with real content, and judge the result on those pages.

2. Images: Usually the Biggest Win

On most Shopify stores, images are the largest single contributor to page weight. Product photos, banners, and collection images are often uploaded at full camera resolution and then rendered at a fraction of that size. Fixing images alone often cuts page weight in half.

Serve the size you actually render

Shopify's image_url filter is the main tool. Request the width you render, not the original:

liquid
{{ product.featured_image | image_url: width: 800 | image_tag: alt: product.title }}

If an image renders at 800 pixels wide on desktop and 400 on mobile, serve those sizes. Do not serve a 4000-pixel original and let the browser shrink it. The browser still downloads the full file.

For responsive images, use srcset so the browser can pick the right size for the device:

liquid
{{ image | image_url: width: 400 | image_tag: srcset: image_srcset, alt: image.alt }}

In practice, theme image helpers handle much of this. The developer's job is to make sure the widths requested match the layout, and that no template is requesting the original image by accident.

Choose the right format and compression

Shopify serves images in modern formats automatically when the browser supports them, so you rarely need to convert formats by hand. What you do need to control is the source: upload images that are already reasonably sized and compressed, not multi-megabyte originals straight from a camera or a design tool. A banner that will render at 1600 pixels wide does not need to be uploaded at 6000 pixels.

Lazy-load everything below the fold

Images in the first viewport — the hero, the first product image — should load immediately. Everything else should load lazily, so the browser does not download images the visitor has not scrolled to yet:

liquid
{{ image | image_url: width: 800 | image_tag: loading: 'lazy', alt: image.alt }}

This one attribute, applied consistently to below-the-fold images, is often worth more than a week of micro-optimisations elsewhere. Check that your theme actually applies it: many themes lazy-load product grid images but forget collection banners, blog images, or section images added later.

3. Apps: The Hidden Weight

Every installed Shopify app can add JavaScript, CSS, or network requests to the storefront — even on pages where the app's feature is not used. A store with twenty apps can easily load more third-party code than theme code.

Audit apps in three steps:

1
List every app and what it does. If nobody on the team can explain what an app is for, it is a candidate for removal.
2
Test with the app disabled. Disable it in a development theme or a duplicate theme, measure the key pages again, and compare. If removing it changes nothing the store needs, and speeds up the page, remove it for real.
3
Replace app features with theme code where it makes sense. A simple announcement bar, a basic FAQ accordion, or a custom badge does not need an app. Theme code for a simple feature is almost always lighter than an app's generic code, because it only does exactly what the store needs.

A useful rule: an app should earn its place on every page it loads on. An app that adds a script to the whole store but is only used on one page should either be scoped to that page, or replaced. Many apps load globally by default, and merchants never notice.

Also check for duplicate functionality. Two review apps, two pop-up apps, or two analytics apps running at once is more common than it should be, and each one adds its own weight.

4. Theme Code: Keep It Scoped and Lean

Theme code causes speed problems in predictable ways. The fixes are mostly about discipline, not cleverness.

Load section code only where it is used

Online Store 2.0 sections can carry their own CSS and JavaScript, loaded only when the section is used on a page. Use that. Code that lives in a global stylesheet or a global script loads on every page, even pages that never use it. Moving section-specific code into {% stylesheet %} and {% javascript %} in the section file is a straightforward win, and it is one of the main advantages of sections over global assets.

Do not load a library for one feature

A full carousel library for a three-slide banner, a heavy animation library for a fade-in, or a date library for formatting one date is almost never worth the download. Native CSS and a few lines of JavaScript handle most storefront interactions, and they do it faster and with fewer failure modes.

Avoid render-blocking surprises

Scripts and stylesheets in the document head block rendering until they load. Keep the head lean: critical CSS inline or early, non-critical scripts deferred, and third-party scripts loaded asynchronously where possible. If a script must run before the page renders, it should be small and necessary — not a tracking script that could wait.

Clean up dead code

Themes accumulate dead code: sections that are no longer used, snippets that are no longer rendered, CSS for layouts that were removed months ago. Dead code still downloads, still parses, and still confuses the next developer. When a section is removed from all templates, remove its file too, after checking that no template still references it.

5. Liquid and Rendering: Fewer Requests, Less Work

Liquid itself is fast, but the way templates use it can create unnecessary work.

Do not loop over large collections without a limit. Rendering every product in a large collection on one page, or looping through all variants for every product in a grid, multiplies work quickly. Paginate, limit, and only render what the page shows.
Avoid repeated expensive filters in loops. If a filter result is used several times inside a loop, assign it once outside the loop or once per iteration, not on every use.
Use {% render %} instead of {% include %}. The older include tag shares variable scope in ways that cause subtle bugs and extra work. render is isolated, predictable, and the current standard.
Cache what does not change. Sections and snippets that render the same output for every visitor do not need to be recomputed on every request in the same way dynamic content does. Shopify's caching handles much of this, but templates that force fresh computation with unnecessary dynamic lookups work against it.

These are not exotic optimisations. They are the difference between a product grid that renders in milliseconds and one that renders noticeably slower because it does ten times the work it needs to.

6. Fonts, Videos, and Third-Party Scripts

After images and apps, the next most common culprits are fonts, videos, and third-party scripts.

Fonts

Limit font families and weights. Each family and weight is a separate download. Two families with two weights each is four downloads; four families with four weights each is sixteen. Pick the smallest set that actually serves the design.
Use font-display: swap. Without it, text can stay invisible while a font loads. With swap, the browser shows fallback text immediately and swaps in the real font when it arrives. Visitors can read the page while fonts load, which is the point.
Preload only the critical font. Preloading every font defeats the purpose. Preload the one font used for headings and body text on the first viewport, and let the rest load normally.

Videos

Never autoplay a large video on mobile. A hero video that looks impressive on desktop can consume a large amount of mobile data and delay the rest of the page. Use a poster image on mobile, or a much smaller video, and let the visitor choose to play it.
Host videos efficiently. Shopify's video hosting and streaming is designed for storefront use. A video embedded from a generic file host, without streaming or compression, will almost always be slower.

Third-party scripts

Audit scripts the same way you audit apps. Analytics, chat widgets, review widgets, and marketing pixels each add requests. Keep the ones that earn their place, remove the ones that do not, and defer the ones that can wait until after the page is interactive.
Load chat and pop-up widgets lazily where possible. A chat widget that loads immediately on every page, before the visitor has any reason to chat, is paying its full cost on every visit for a feature used on a fraction of them.

7. Caching, CDN, and What Shopify Already Handles

It is worth knowing what you do not need to fix, because Shopify already handles it:

Shopify serves storefronts through a global CDN. Static assets — images, CSS, JavaScript — are served from servers close to the visitor. You do not need to set up your own CDN for a standard Shopify store.
Browser caching for static assets is handled by Shopify. Repeat visits are faster than first visits because assets are cached, without any theme work.
Shopify optimises images on delivery. When you request a sized image through image_url, Shopify serves an optimised version. Your job is to request the right size, not to build your own image pipeline.

What Shopify does not handle for you is the content of your pages: how many images you put on them, how many apps you install, how much code you load, and how your Liquid is written. That is where developer work matters, and it is where this guide focuses.

8. A Practical Optimisation Checklist

Work through this list in order, measuring after each step. Stop when the key pages are fast enough for real visitors — perfection on a lab score is not the goal.

1
Baseline: record first paint, largest paint, and page weight for homepage, collection, and product pages.
2
Images: serve rendered sizes, lazy-load below the fold, compress uploads.
3
Apps: list, test-disabled, and remove or replace anything that does not earn its weight.
4
Theme code: move section code into sections, remove dead code, avoid libraries for single features.
5
Fonts: limit families and weights, use font-display: swap, preload only the critical font.
6
Videos and scripts: poster images on mobile, defer non-critical third-party scripts.
7
Liquid: limit loops, avoid repeated expensive filters, use render.
8
Re-measure: compare against the baseline on the same pages, on a real phone if possible.
9
Repeat monthly: speed regresses as apps are added and content grows. A monthly check catches it before visitors do.

Common mistakes, and the fix for each:

SymptomLikely causeFix
Page weight over several megabytesFull-size original imagesServe rendered sizes with image_url
Slow first paint on mobileToo many head scripts and fontsDefer scripts, limit font weights
Page feels slow but lab score is fineThird-party scripts on real devicesAudit apps and scripts, test on a real phone
Speed regressed after a theme changeNew app or global code addedDiff the change, scope code to where it is used
Images load all at onceMissing lazy loadingAdd loading: 'lazy' below the fold

9. When Speed Work Stops Paying Off

There is a point of diminishing returns. Once key pages load quickly on a real phone, further lab-score chasing usually means removing features visitors actually use, or rewriting working code for a marginal gain. That trade is rarely worth it.

A better use of time at that point is content and conversion work: clearer product pages, better photography, simpler checkout steps, and honest, useful information. Speed gets visitors to the page. What is on the page is what makes them buy.

Conclusion

Shopify store speed is not a mystery, and it is not a single fix. It is the sum of ordinary decisions: image sizes, app choices, scoped code, font discipline, and lazy loading. Measure the real pages, fix the biggest contributor first, measure again, and repeat.

Most stores do not need a rebuild to get faster. They need an audit, a few removals, and a habit of checking speed when something new is added. Do that, and the store stays fast — not just on the day it is optimised, but on every day after.

Next Recommended Reads

#Shopify#Performance#Shopify Themes#Liquid#Page Speed#E-commerce#Frontend#Optimization
Yash Nandvana

Yash Nandvana• Full Stack Developer

Full Stack & Shopify Developer building scalable web apps, developer tools, and AI solutions.

Learn more about Yash
wingsLogo

FROM CONCEPT TO CREATION

LET'S MAKE IT HAPPEN!

I'm available for full-time roles & freelance projects.

I thrive on crafting dynamic web applications, and
delivering seamless user experiences.

>_~/terminal