· 5 min read
Why We Build Client Sites with Astro
A technical breakdown of how Astro's island architecture, content collections, and build pipeline make it the right default for most production web projects.
· 10 min read · shopify · performance · e-commerce
Why your Shopify store is slow and how to fix it — covering theme bloat, app overhead, image optimization, Liquid rendering, and Core Web Vitals improvements with real metrics.
Ten Peaks Tech
A slow Shopify store costs you money in ways that don’t show up on a dashboard. Visitors bounce before the page finishes loading. Google ranks you lower in search results. Conversion rates drop — studies consistently show that every additional second of load time reduces conversions by 7-10%.
We’ve optimized Shopify stores across several industries, including a deep performance overhaul for Audeze, a premium headphone manufacturer. That project took their mobile Lighthouse score from the low 30s to above 90 and cut their Largest Contentful Paint in half. This guide covers the same techniques we used, adapted so you can apply them to your own store.
Shopify’s infrastructure is actually fast. Their CDN is global, their servers are well-optimized, and their base themes load quickly out of the box. The performance problems come from what merchants add on top.
Three things account for 90% of Shopify performance issues:
Let’s break each one down.
Premium Shopify themes compete on features. More features mean more sales on the theme marketplace. But every feature — mega menus, animation libraries, product quick-views, countdown timers — adds code that loads on every page, whether you use the feature or not.
Open Chrome DevTools, go to the Coverage tab (Ctrl+Shift+P, type “coverage”), and reload your page. This shows you exactly how much of your CSS and JavaScript is actually used on that page. We routinely find that 60-80% of a theme’s CSS is unused on any given page.
Option 1: Remove unused features. Most themes have settings to disable features like quick-view modals, product tabs, or animations. Disabling them in the theme settings sometimes removes the associated code, but not always — many themes load the code regardless.
Option 2: Audit and trim the theme code. This requires a developer who understands Liquid, CSS, and JavaScript. The process is:
Option 3: Start from a minimal base. Shopify’s Dawn theme is their reference implementation. It’s intentionally lean and well-structured. If your current theme is beyond saving, migrating to Dawn (or a Dawn-based theme) and adding only what you need often produces better results than trying to optimize a bloated theme.
This is the biggest performance killer we see. A typical Shopify store has 8-15 apps installed, and each one adds code to the storefront.
Here’s what a single app injection can look like:
Multiply that by 10 apps and you’re loading an extra 1-2MB of resources before your actual page content renders.
layout/theme.liquid file for leftover code snippets from removed apps.defer or async attributes. Some apps break when deferred, so test carefully.When we optimized the Audeze store, app consolidation was one of the highest-impact changes. We replaced several apps with native theme functionality, reducing external script loads by over 60%.
Images are typically the largest assets on any e-commerce page. Shopify has built-in image optimization, but it only works if you use it correctly.
Shopify serves images through their CDN and supports URL parameters for resizing and format conversion. In Liquid, use the image_url filter with width parameters:
{{ product.featured_image | image_url: width: 600 }}
This serves a 600px wide image instead of the full-resolution upload. For responsive images, generate a srcset:
<img
srcset="
{{ image | image_url: width: 400 }} 400w,
{{ image | image_url: width: 800 }} 800w,
{{ image | image_url: width: 1200 }} 1200w
"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
src="{{ image | image_url: width: 800 }}"
loading="lazy"
alt="{{ image.alt }}"
/>
Add loading="lazy" to every image that isn’t visible on initial page load. Do NOT lazy-load your hero image or the first product image — those are your LCP elements and need to load immediately. For LCP images, add fetchpriority="high" instead.
Before uploading to Shopify, run images through a tool like Squoosh, TinyPNG, or ImageOptim. Target 80-85% quality for product images — the visual difference is imperceptible, but the file size difference is 40-60%.
Liquid is Shopify’s templating language, and inefficient Liquid code slows down server-side rendering, increasing Time to First Byte (TTFB).
Nested loops. Looping through all products inside a loop through all collections creates O(n*m) complexity. If you have 50 collections and 500 products, that’s 25,000 iterations on every page load.
{% comment %} BAD: Nested loop {% endcomment %}
{% for collection in collections %}
{% for product in collection.products %}
...
{% endfor %}
{% endfor %}
{% comment %} BETTER: Use a specific collection {% endcomment %}
{% for product in collections['featured'].products limit: 12 %}
...
{% endfor %}
Excessive include calls. Each {% include %} (or {% render %}) call has overhead. Rendering a snippet inside a loop of 50 products means 50 snippet calls. Where possible, inline the snippet content for performance-critical loops.
Unscoped for loops. Always use limit on loops that display product grids. Loading 200 products when you only display 12 wastes rendering time.
Section rendering and Liquid caching happen automatically for most content, but dynamic content (cart data, customer-specific pricing) bypasses the cache. Minimize the amount of dynamic content on high-traffic pages like your homepage and collection pages.
Google uses three Core Web Vitals to evaluate page experience:
LCP measures when the largest visible element finishes rendering. On Shopify stores, this is almost always the hero image or the first product image.
How to improve it:
<link rel="preload" as="image">fetchpriority="high" on the LCP image elementCLS measures visual stability — how much the page jumps around while loading. Common causes on Shopify: images without explicit dimensions, fonts that swap and change layout, and app widgets that inject content after page load.
How to improve it:
width and height attributes on all imagesfont-display: swap with a fallback font that matches your custom font’s metricsINP measures responsiveness — how quickly the page responds to user interactions. Heavy JavaScript from apps and themes is the usual culprit.
How to improve it:
requestIdleCallback or setTimeoutWhen Audeze came to us, their Shopify store had a mobile Lighthouse score in the low 30s and page load times exceeding 6 seconds. For a brand selling $2,000+ headphones, that performance was actively losing sales.
Here’s what we did:
font-display rules, and preloaded critical font files.The results:
You can read more about this project and our other e-commerce work on our services page.
If you want to tackle this yourself, here’s the order we recommend:
If your store’s Lighthouse score is below 50 on mobile, or your Core Web Vitals are failing in Google Search Console, optimization is likely costing you revenue every day you delay.
We offer Shopify performance audits that identify the specific bottlenecks on your store and prioritize fixes by impact. If you want to talk through your store’s performance, book a free consultation — we’ll take a look at your metrics and tell you where the biggest opportunities are.
Keep reading
· 5 min read
A technical breakdown of how Astro's island architecture, content collections, and build pipeline make it the right default for most production web projects.
A senior engineer replies within one business day.