Skip to content

Speed

WebP, AVIF, and Shopify's image pipeline

Published

The Shopify image pipeline in 2026

Shopify's image pipeline auto-emits AVIF first, WebP second, original format third — as long as theme code uses the image_url Liquid filter (or img_url in older themes). The pipeline negotiates format per browser via Accept headers: Chrome and Safari get AVIF; older browsers fall back to WebP or the original JPEG/PNG. AVIF is roughly 30% smaller than WebP at equivalent quality; WebP is roughly 25% smaller than JPEG. The compounding effect: a 400KB JPEG source becomes a 180KB AVIF for most buyers, served from Shopify's global CDN.

The catch: themes that use raw <img src=...> tags instead of {{ product.image | image_url: width: 800 }} bypass the auto-format negotiation entirely. The browser receives the original source file in the original format at the original size. This is the silent reason 'why is my Shopify store slow' surveys keep finding answer: the theme isn't using the pipeline.

The image_url Liquid filter

image_url is the modern Shopify filter that emits responsive, format-negotiated image URLs. It accepts width (and optional height, crop, format hint) and returns a CDN URL that Shopify resolves per request. The browser sends its Accept header; Shopify returns AVIF if the browser supports it, WebP if not, original format otherwise. img_url is the older equivalent — still supported, but image_url is preferred on Online Store 2.0 themes and required for Hydrogen.

liquid image_url usage in product card snippets
 <!-- Single-width usage --> <img src="{{ product.featured_image | image_url: width: 800 }}" width="800" height="800" alt="{{ product.featured_image.alt | escape }}" loading="lazy" /> 

The filter automatically picks the right format. Don't add format: 'webp' or format: 'avif' unless you have a specific reason — Shopify's automatic negotiation is faster and more compatible than manual hints.

The srcset pattern that doesn't double-load

A responsive srcset lets the browser pick the right image width for the device. The Shopify-correct pattern: declare 3-4 widths in srcset, set sizes to the displayed width, and let the browser choose. The trap: declaring widths that don't match the displayed size (10 widths from 200px to 4000px on an image that displays at 400px) wastes Shopify's pipeline work without benefit. Pick widths that cover real device sizes.

liquid Responsive image with srcset on a product card
 <img src="{{ product.featured_image | image_url: width: 800 }}" srcset="{{ product.featured_image | image_url: width: 400 }} 400w,
          {{ product.featured_image | image_url: width: 600 }} 600w,
          {{ product.featured_image | image_url: width: 800 }} 800w,
          {{ product.featured_image | image_url: width: 1200 }} 1200w" sizes="(max-width: 768px) 50vw, 25vw" width="800" height="800" alt="{{ product.featured_image.alt | escape }}" loading="lazy" /> 

Four widths cover most card layouts. The sizes attribute tells the browser the displayed width — 50vw on mobile (one card per row at half viewport), 25vw on desktop (four cards per row). The browser picks the width from srcset that best matches the displayed size at the device's DPR.

When to override the auto-format

The auto-format negotiation is usually correct. Three cases where you might override. (1) Transparent PNGs that AVIF compresses poorly — force WebP via format: 'webp'. (2) Animated GIFs that the pipeline doesn't optimise — host externally or convert to MP4 + video tag. (3) Strict CSP environments where format negotiation breaks — force a specific format via the format hint. All three are rare. The default behaviour is right for 99% of stores.

Shopify's Optimizing for AI doc4 recommends "high-quality images with descriptive alt text" — image quality matters for AI shopping engines that surface visual product cards. Don't compress so aggressively that visual quality degrades to save 30KB. The pipeline's defaults balance quality and size; trust them unless you have a measured reason to override.

Upload rules — file name and source size

Three rules at upload time. (1) Set the file name BEFORE uploading — Shopify's Optimizing site structure doc confirms file names cannot be modified after upload. (2) Resize the source to the maximum displayed width × 2 — for a hero image that displays at 1600px, upload at 1600-3200px max, not 4000-6000px. (3) Use descriptive alt text in the media library after upload.

Shopify's optimize-site doc2 is explicit: image file names cannot be modified post-upload. A file uploaded as IMG_4271.jpeg stays IMG_4271.jpeg forever unless you delete and re-upload with the new name. Google reads the file name as a secondary content signal — ceramide-moisturizer-50ml-jar.jpg beats IMG_4271.jpeg on otherwise-identical images.

Alt text rule: describe what the image shows, not what query you want to rank for. Shopify's SEO overview1 confirms alt text is customizable per image via the media library. Use natural language; never keyword-stuff alt attributes. AI shopping engines flag keyword-stuffed alt text as low-trust.