Why Is My Shopify Store Slow? A Developer's Checklist to Fix It
Shopify's servers and CDN are fast. When a Shopify store is slow, it's almost always caused by what's been added on top: apps injecting scripts, oversized images, a heavy hero video, or Liquid code doing far more work than it needs to. This is the checklist I go through when a client asks me to speed up their store, roughly in order of impact.
Measure before changing anything
Use two kinds of data:
- Field data (real visitors): the Core Web Vitals report in Google Search Console, and the "Discover what your real users are experiencing" section at the top of PageSpeed Insights. This is what Google uses, and what your customers actually experience.
- Lab data (a single test run): the Lighthouse score in PageSpeed Insights or Chrome DevTools. Useful for finding causes, but it varies from run to run, so don't chase single points.
Test the homepage, a collection page and a product page, on mobile. Write the numbers down so you can compare after each change.
1. Remove what apps left behind
Apps are the number one cause of slow Shopify stores. Each one can add JavaScript, CSS, fonts and tracking requests to every page.
- List what loads. In Chrome DevTools, open the Network tab, reload the page, and sort by domain. Every domain that isn't your store or
cdn.shopify.comis a third party. Note which app each belongs to. - Delete apps you don't use. Be honest about the ones installed "to try out".
- Remove leftover code. Older apps added code directly to your theme, and that code often stays after the app is uninstalled. Look in
layout/theme.liquidfor<script>tags and{% render %}tags referring to apps you no longer have. Broken leftovers sometimes show up as visible errors, see fixing "Could not find asset" Liquid errors. - Check app embeds. In Customize → App embeds, disable embeds for apps you don't need on the storefront.
2. Serve properly sized images
A 3000px-wide product photo shown at 400px wide wastes a lot of bandwidth on mobile. Shopify can resize images on the fly, so the theme just has to ask for the right size. In Liquid, use image_url with a width and image_tag with widths and sizes, which generates a responsive srcset:
{{ product.featured_image
| image_url: width: 1200
| image_tag:
widths: '300, 500, 800, 1200',
sizes: '(min-width: 990px) 50vw, 100vw',
loading: 'lazy',
alt: product.featured_image.alt }}
Most modern themes already do this, but custom sections added by freelancers or page builders often don't. Look for img_url: 'master' or a full-size image_url without a width. Those load the original upload.
3. Don't lazy-load the main image
Lazy loading is great for images further down the page, but bad for the first big image visitors see (the hero banner or main product image). That image is usually your Largest Contentful Paint (LCP) element, and lazy-loading it delays LCP. For that one image, load it eagerly with high priority:
{{ section.settings.image
| image_url: width: 1600
| image_tag:
widths: '600, 900, 1200, 1600',
sizes: '100vw',
loading: 'eager',
fetchpriority: 'high' }}
Keep loading: 'lazy' for everything below the fold.
4. Rethink the autoplay hero video
A full-screen background video is often several megabytes, and on mobile it competes with everything else for bandwidth. Options, from best to acceptable:
- Replace it with a well-compressed image on mobile and keep the video on desktop only.
- Show a poster image first and load the video after the page has loaded.
- At minimum, compress it hard (a few hundred KB is achievable for a short loop) and host it in Shopify Files rather than an external embed.
5. Tame third-party scripts
Chat widgets, review widgets, heatmaps and marketing pixels are often worse for Interaction to Next Paint (INP), how quickly the page responds to taps, than for load time. They tie up the browser's main thread.
- Move tracking pixels to Settings → Customer events (Shopify's web pixels), which run in a sandbox instead of on the main page. Many marketing apps now install this way.
- Load chat widgets only after the customer interacts with the page, or after a delay, instead of on page load.
- Remove duplicate tracking. It's common to find the same Google or Meta tag installed twice, once by an app and once by hand.
6. Load fonts efficiently
Stick to one or two font families from Shopify's font library, and make sure text is visible while fonts load. In themes that use font_face, pass font_display: 'swap':
{{ settings.type_body_font | font_face: font_display: 'swap' }}
Custom fonts loaded from external services add extra connections. Hosting the font files in the theme's assets folder avoids that.
7. Fix slow Liquid
If the first byte of HTML itself is slow (high Time to First Byte in PageSpeed Insights), the theme's Liquid is doing too much work on the server. The Shopify Theme Inspector for Chrome extension shows exactly which Liquid files and lines take the longest to render. Common problems:
- Looping over large collections, like
collections.all.products, to build menus, upsells or "related products". - Nested loops: products, then each product's variants, then each variant's metafields.
- Using the old
{% include %}tag instead of{% render %}.
Shopify's native product recommendations and Search & Discovery features replace most "loop through everything" code with a single fast request.
8. Cut homepage sections
Homepages accumulate sections: three sliders, two featured collections, an Instagram feed and a video. Each adds images and scripts. Keep the sections that actually drive clicks (your analytics will show which) and remove the rest.
When it's the theme itself
If a store is still slow after all of the above, the theme may simply be heavy: lots of JavaScript, a page builder layered on top, or years of patches. At that point, rebuilding the key templates on clean Online Store 2.0 sections (Dawn is a fast base) is often less work than optimizing around the problems. That's the approach I took for Inversia's redesign: native OS 2.0 sections, no page builders.
Measure again
Re-run your tests after each change, not just at the end, so you know what actually helped. Then wait about 28 days for the Search Console field data to catch up, since that report is based on a rolling window of real visits.
Written by
Sameer Hussain, Senior Shopify & WordPress Engineer
Top Rated on Upwork and the Shopify & WordPress engineer at Inceptus Digital. Short on time, or not comfortable editing code? Send me your URL and the error on Upwork and I'll tell you how I'd fix it before you commit.
Need Custom Engineering or Growth Systems?
Our team helps ambitious brands build bespoke software, AI integrations, and high-conversion platforms.