Use the picture element when you have separate mobile and desktop images
Replace CSS-toggled mobile and desktop hero image pairs with a single <picture> element so the browser downloads only the image that matches the viewport.
Many Shopify themes render two separate <img> tags for the hero, one for desktop and one for mobile, and toggle visibility with CSS display: none at a breakpoint. The browser can't know that one of the images is hidden, so it downloads both. On a mobile device, this means the desktop hero (often a wide, high-resolution image) downloads alongside the mobile hero, wasting bandwidth and competing for connection resources.
A second problem compounds the first: fetchpriority="high" is often applied only to the desktop image using the Liquid image_tag filter, because the mobile image is rendered in a separate code path that omits it. On mobile, typically 60 to 75% of storefront traffic, the LCP image downloads at default priority instead of high, adding hundreds of milliseconds to LCP.
The <picture> element solves both problems. The browser evaluates the <source media="..."> conditions and downloads only the matching image. fetchpriority="high" goes on the inner <img> fallback element and applies to whichever source the browser selects.
Replace the two-image pattern with a <picture> element. The mobile source comes first so that the browser picks it when the media query matches. The desktop source is the fallback.
Key points:
fetchpriority="high"goes on the<img>element only. It applies to whichever<source>the browser selects. Don't put it on<source>because the attribute isn't valid there.widthandheighton each<source>prevent layout shift. The browser uses the dimensions of the matched source to reserve space before the image loads.- The
<img>fallback uses the desktop image. - Remove the CSS rules that toggle
.hero__image--mobileand.hero__image--desktopvisibility. They're no longer needed.
When the merchant hasn't uploaded a separate mobile image, the desktop source is the only one and the <picture> degrades gracefully to a single responsive image.
Anchor to ExamplesExamples
Anchor to Detecting the anti-patternDetecting the anti-pattern
In Chrome DevTools, check the Network panel at both mobile and desktop viewport widths. If two hero-sized images download on a single page load and the page uses CSS classes like --mobile and --desktop with display: none media queries, then the theme is using the two-image pattern.
In the theme code, look for two image_tag calls in the hero section, one with a --desktop class and one with --mobile. Check whether both calls include fetchpriority:. Frequently only the desktop one does.
Anchor to TestingTesting
- In the Chrome DevTools Network panel, at a mobile viewport, verify that only one hero image downloads. Enable the Priority column and confirm the hero image loads at High priority.
- Toggle between mobile and desktop viewports in Device Mode and verify the correct image appears at each breakpoint.
- Check that
widthandheighton the<source>elements prevent layout shift during image load.
Anchor to ReferencesReferences
<picture>element, MDNimage_tagfilterimage_urlfilter- Use responsive images
- Prevent image layout shift
- Mark the LCP image with
fetchpriority="high"