How Shopify stores waste 40% of their bandwidth on images
Most Shopify stores are serving images 3-5x larger than they need to be. Here's exactly where the waste happens and what to do about it.
Shopify does not automatically optimize your images. You need to handle format conversion, resizing, and metadata stripping yourself, or your store is wasting a significant share of its image bandwidth on every page load.
Most Shopify store owners assume the platform handles image delivery. It handles part of it. The gap between what Shopify does automatically and what actually needs to happen is costing stores, across the ones I've audited, somewhere between 35% and 45% of their total image bandwidth.
I've audited a lot of e-commerce stores over the past few years: fashion, home goods, supplements, a few high-SKU-count general merchants. The same mistakes show up almost mechanically every time.
Shopify's default image behavior
Shopify runs on a CDN and supports image URL parameters for resizing. You can append _600x.jpg or _600x600_crop_center.jpg to most image URLs to get a resized version. It added WebP support in 2020 for storefronts using the image_url Liquid filter with format: 'webp'.
It doesn't serve correctly-sized images based on device, strip EXIF, or compress to an optimal byte size. And unless your theme explicitly uses image_url with width and format parameters, the CDN serves whatever the photographer uploaded, at the quality they exported it.
Where does the bandwidth actually go?
Oversized source files
Product photography comes out of a camera or Lightroom at 4000+ pixels wide, typically 10-25 MB per file. Shopify will serve that file as-is unless the theme requests a resized version.
Run this in DevTools on any mid-size Shopify store:
performance.getEntriesByType('resource')
.filter(r => r.initiatorType === 'img')
.map(r => ({ url: r.name, kb: Math.round(r.transferSize / 1024) }))
.sort((a, b) => b.kb - a.kb)
.slice(0, 10)
Consistently in my testing, the top 10 images account for 60-80% of total image transfer. The largest offender is usually a hero banner or lifestyle shot served at 3200px because the theme's <img> tag doesn't specify a width parameter.
Responsive sizing cuts mobile transfer 60-70%
Adding srcset with a few width breakpoints typically cuts mobile image transfer by 60-70% on its own. A mobile visitor with a 390px screen doesn't need a 1200px image. Converting to WebP compounds that. Google's web.dev documentation at web.dev/serve-images-webp puts the average WebP file at 25-35% smaller than an equivalent JPEG at the same perceptual quality, and I've seen similar numbers consistently in catalog conversions I've run.
EXIF metadata on every image
A JPEG shot on a modern camera carries 50-150 KB of EXIF metadata automatically: GPS coordinates, camera model, lens info, exposure settings, sometimes a full-res thumbnail embedded in the file itself. Across a 500-SKU catalog, that's 25-75 MB of pure metadata sent to every visitor loading your collection pages.
On a catalog audit I ran last year, stripping EXIF from 800 product images reduced total image storage by 18% and cut average page transfer by 40 KB, before any format conversion.
Shopify does not strip EXIF on upload.
JPEG when WebP would do
Shopify's image_url filter supports WebP via format: 'webp', but only if your theme actually uses that filter. Most themes built before 2021, and plenty built after, still use the older img_url filter, which doesn't support format conversion.
Check your theme's product-card.liquid or equivalent. If you see | img_url without a format parameter, you're serving JPEG to every browser, including Chrome and Firefox, which have supported WebP since 2013.
The fix
For themes you control, the minimum viable change is updating image tags to use image_url with format: 'webp' and a srcset covering 3-4 width breakpoints:
{% assign img_url = product.featured_image | image_url: width: 800, format: 'webp' %}
<img
src="{{ img_url }}"
srcset="
{{ product.featured_image | image_url: width: 400, format: 'webp' }} 400w,
{{ product.featured_image | image_url: width: 800, format: 'webp' }} 800w,
{{ product.featured_image | image_url: width: 1200, format: 'webp' }} 1200w
"
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
width="800"
height="800"
loading="lazy"
alt="{{ product.featured_image.alt | escape }}"
>
That one change eliminates most of the waste on collection pages.
For the upload pipeline, you need to strip EXIF and compress before anything hits Shopify's servers. Tools like sharp (Node.js) or ImageMagick handle this in a pre-upload script. If you're managing a large catalog, a DAM like Pixel Wand handles it at the source: strip metadata, convert to WebP, generate derivatives, so you're pushing the optimized version to Shopify rather than the raw export.
A note on conversion impact
My honest take, having made the business case for this to CMOs who were skeptical: the stores that see the biggest lift from image optimization are mobile-heavy stores with slower average connection speeds and a long consideration phase. A supplements brand with a 90-second average session on mobile saw meaningful conversion improvement after we fixed their image delivery. A fashion brand with an already-fast desktop-dominant audience saw smaller gains.
The commonly cited benchmarks around page speed and conversion are real effects, but the magnitude varies a lot by store and audience. I'd be skeptical of anyone promising a specific percentage. In my experience, mobile visitors on mid-tier Android devices show the most consistent response, and collection pages matter more than PDPs because that's where most bounce happens.
Baseline audit
- Open Chrome DevTools on your store's collection page.
- Go to the Network tab, filter by
Img. - Sort by Size descending.
- Add up the total transfer values.
Compare that to what you'd expect if every image were served as WebP at the correct display size. The gap is your waste. On most stores I've audited, it's between 35% and 55% of total image bytes. PageSpeed Insights flags this directly under "Serve images in next-gen formats" and "Properly size images," with a time estimate attached to each.
FAQ
Shopify CDN vs. image optimizer: what's the difference?
Shopify's CDN delivers images fast. An image optimizer changes the image itself: format, dimensions, compression, metadata. These are different layers. Shopify's CDN doesn't transform images unless you use its Liquid parameters explicitly, which means an unoptimized image gets delivered fast. It's still an unoptimized image, just delivered quickly. The CDN is the truck; the optimizer is the packing crew. You need both doing their job.
Pull the DevTools snippet on your collection page today, identify the top 10 images by file size, and re-export or re-upload WebP versions at the correct display dimensions. That single pass covers the majority of recoverable bandwidth before you touch a line of theme code.