Your Shopify store loads in 5 seconds. You're losing 20% of your visitors before they see a single product.
Google's data is clear: 53% of mobile users abandon a site that takes longer than 3 seconds to load. For every additional second of load time, conversions drop by 7%. At 5 seconds versus 2 seconds, you've already handed away a significant portion of the revenue your ads and SEO are sending you.
The frustrating part: most Shopify speed problems are not caused by Shopify itself. They're caused by avoidable decisions — theme bloat, too many apps, unoptimized images, render-blocking scripts — that a developer can fix systematically.
Here's exactly what's slowing your store down and how to fix it at the code level.
How to Accurately Measure Where the Speed Problem Is
Before fixing anything, measure correctly. PageSpeed Insights (Google's free tool at pagespeed.web.dev) gives you a real-world performance score and, more importantly, identifies the specific issues causing slowness.
Run your homepage, your most important product page, and your collection page. Mobile scores matter more than desktop — Google uses mobile-first indexing.
The Core Web Vitals metrics you're targeting:
Largest Contentful Paint (LCP) — How long until the main content of the page is visible. Target under 2.5 seconds. This is the most important metric for perceived performance.
Cumulative Layout Shift (CLS) — How much the page jumps around as it loads. Target under 0.1. Layout shifts frustrate users and signal poor code quality.
Interaction to Next Paint (INP) — How quickly the page responds to user input. Target under 200ms. Slow interactivity makes the store feel broken.
Write down your current scores, then systematically address the issues PageSpeed flags.
Problem 1 — Render-Blocking Scripts From Apps
This is the single most common cause of slow Shopify stores and the one most store owners don't realize they're creating.
Every app you install injects JavaScript into your store. Some apps inject their scripts into the <head> tag of your theme, which means the browser has to download and execute that script before it can render anything on the page. With five apps doing this, you might have 500KB of JavaScript that has to load before a customer sees your products.
The diagnosis: Open Chrome DevTools → Performance tab → record a page load. Look for "render blocking resources" in the waterfall. Each one is a script holding up your first paint.
The fix: Move app scripts to load asynchronously or defer them. Most app scripts don't need to execute before the page renders — they need to execute after. In your theme's layout/theme.liquid, change blocking script tags:
<!-- Blocking — don't do this -->
<script src="app-script.js"></script>
<!-- Non-blocking — do this -->
<script src="app-script.js" defer></script>
<!-- or for truly non-critical scripts -->
<script src="app-script.js" async></script>For app scripts you can't directly control (they're injected by the app), use a script manager or talk to the app developer. Some apps have a "defer loading" option in their settings.
The harder fix: Audit every installed app. Any app whose script loads on every page but is only used on one page (a product configurator app loading on the homepage, for example) should be conditionally loaded. In Liquid:
{% if template == 'product' %}
{{ 'app-script.js' | asset_url | script_tag }}
{% endif %}Problem 2 — Unoptimized Images
Images are almost always the heaviest assets on a Shopify page. A single product photo that hasn't been properly optimized can be 2-4MB — larger than everything else on the page combined.
The diagnosis: In PageSpeed Insights, look for "Properly size images," "Serve images in next-gen formats," and "Efficiently encode images." These flags tell you exactly which images are the problem.
Fix 1 — Use Shopify's built-in image transformation. Shopify stores original images and can serve them at any size and in WebP format automatically. In your theme Liquid code, use image_url with explicit size parameters:
<!-- Don't serve full-size images for thumbnails -->
{{ product.featured_image | image_url: width: 800 | image_tag }}
<!-- Use srcset for responsive images -->
<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: 768px) 100vw, 50vw"
loading="lazy"
width="800"
height="800"
alt="{{ product.featured_image.alt | escape }}"
>Fix 2 — Add loading="lazy" to below-the-fold images. Images that aren't visible on initial page load should be deferred. Only your hero image and above-the-fold content should load eagerly.
Fix 3 — Set explicit width and height on all images. This prevents layout shift (CLS) by letting the browser reserve space before the image loads.
Problem 3 — Theme Code Bloat
Many popular Shopify themes are built to handle every possible use case — animations, mega menus, video backgrounds, complex filtering. The CSS and JavaScript for all those features loads on every page, even the pages that don't use them.
The diagnosis: In Chrome DevTools → Coverage tab (Ctrl+Shift+P → "Show Coverage"), you'll see what percentage of loaded CSS and JavaScript is actually used on each page. Seeing 80%+ unused CSS is common in bloated themes.
The fix: This requires real development work, but it's transformative for performance.
For CSS: Remove unused styles from your theme's CSS. You can use PurgeCSS to automate this — it scans your templates and removes any CSS class that isn't used. For a Shopify theme, this typically reduces CSS from 150KB to under 20KB.
For JavaScript: Split your theme's JS into modules and only load what each template needs. The homepage doesn't need product configurator code. The product page doesn't need blog filtering code.
If you're on Dawn or another Shopify 2.0 theme, you can also disable unused sections and features directly in the theme editor to reduce what loads. But manual CSS/JS splitting by a developer achieves far better results.
Problem 4 — No Lazy Loading on Collection Pages
Collection pages with 24, 48, or 96 products often load all product images simultaneously on page load, creating a massive network request queue that delays the visible products.
The fix: Implement Intersection Observer in JavaScript to lazy load products as the user scrolls:
const productCards = document.querySelectorAll(".product-card img");
const imageObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.srcset = img.dataset.srcset;
imageObserver.unobserve(img);
}
});
},
{ rootMargin: "200px" },
);
productCards.forEach((img) => imageObserver.observe(img));In your Liquid template, replace src with data-src on product cards below the first row, and add a low-quality placeholder or blur-up effect while the real image loads.
Problem 5 — Missing Browser Caching and CDN Configuration
Repeat visitors to your store should load pages faster than first-time visitors because static assets (CSS, JS, images) should be cached in their browser.
Check your cache headers: In Chrome DevTools → Network tab, look at the response headers for your theme's CSS and JS files. You want to see Cache-Control: max-age=31536000 (one year) for versioned assets.
Shopify's CDN handles caching for assets uploaded to your theme's Assets folder. But inline scripts and styles embedded directly in Liquid templates don't benefit from CDN caching. Move any reusable JavaScript into theme asset files so the CDN can cache them.
What Good Performance Numbers Look Like
After implementing these fixes on a typical Shopify store:
| Metric | Before | After |
|---|---|---|
| PageSpeed Mobile | 35–55 | 80–95 |
| LCP | 4–7 seconds | 1.5–2.5 seconds |
| Total page size | 4–8 MB | 800KB–1.5MB |
| Number of requests | 80–150 | 25–45 |
These aren't theoretical numbers — they're typical results from a proper performance audit and remediation on a mid-complexity Shopify store.
What This Work Actually Involves
A full Shopify performance optimization engagement typically involves:
- PageSpeed audit on key pages (homepage, product, collection, cart)
- Script audit — identifying and deferring render-blocking app and theme scripts
- Image audit — implementing responsive images with proper srcsets and lazy loading
- Theme CSS/JS audit — removing unused code, splitting by template
- Liquid template optimization — reducing database calls, caching fragment data
- Post-optimization measurement and reporting
This is developer work. If you try to address performance only through PageSpeed suggestions without understanding the underlying code, you'll make surface improvements but miss the structural issues that cause the most slowness.
If your Shopify store's PageSpeed score is below 70 on mobile, or your LCP is above 3 seconds, you have a real problem that's costing you conversions every day. I can run a full performance audit and fix the specific issues causing your slowness — reach out and I'll start with a free diagnostic.




