Key takeaways
- Most modern Shopify themes (Dawn, Craft, Sense) include
loading="lazy"on images by default.- To check: right-click any image on your store → Inspect → look for
loading="lazy"in the HTML.- Your hero/banner image should NOT be lazy loaded — it’s the Largest Contentful Paint element and must load immediately.
- To add lazy loading manually: edit image tags in section or snippet Liquid files to include
loading="lazy".
Lazy loading delays the loading of images until they’re about to enter the viewport. Instead of downloading every image on a page when it first loads, the browser only downloads images as the visitor scrolls down to them. For long Shopify product or collection pages with dozens of images, this can dramatically reduce initial page load time.
How to lazy load images in Shopify
Step 1 — Check if your theme already does it.
Right-click any image on your storefront → Inspect → look at the <img> tag in the HTML. If you see loading="lazy", your theme already includes lazy loading for that image.
Modern Shopify themes built on Dawn (the official Shopify theme) include loading="lazy" by default for:
- Collection page product images
- Gallery images below the fold
- Blog post featured images
- Section images that aren’t the first visible content
If your theme was built after 2021, it very likely includes this already.
Related: Compress Images in Shopify.
How to add lazy loading to images manually
If your theme doesn’t include loading="lazy", add it to the image tags in your section and snippet Liquid files.
Step 1 - Duplicate your theme.
Step 2 - In the code editor, find the section or snippet where the image is rendered. Common locations:
sections/main-collection-product-grid.liquid— collection page product imagessections/featured-collection.liquid— homepage featured productssnippets/card-product.liquid— product card template used across multiple sections
Step 3 - Find the <img> tag and add loading="lazy":
<!-- Before -->
<img
src="{{ product.featured_image | img_url: '400x' }}"
alt="{{ product.featured_image.alt }}"
width="400"
height="400"
/>
<!-- After -->
<img
src="{{ product.featured_image | img_url: '400x' }}"
alt="{{ product.featured_image.alt }}"
width="400"
height="400"
loading="lazy"
/>
Step 4 - Save and test. Use Chrome DevTools Network tab to confirm images are loading only as you scroll.
How to add lazy loading in Shopify using Shopify’s image_tag filter
The modern Shopify way to render images is using the image_tag filter, which handles lazy loading (and other best practices) automatically:
{{ product.featured_image | image_url: width: 400 | image_tag: loading: 'lazy', alt: product.featured_image.alt }}
This generates an <img> tag with lazy loading, proper width/height attributes, and srcset for responsive images. If your theme is using older img_url syntax, updating to image_url + image_tag is the cleaner upgrade.
Which images should NOT be lazy loaded
The hero image / banner image. This is typically the Largest Contentful Paint (LCP) element — the largest visible image when the page first loads. LCP is a Core Web Vital that directly affects your Google ranking.
Lazy loading your hero image means the browser waits to download it until it “needs” to — but it needs it immediately. This hurts your LCP score significantly.
If your hero image has loading="lazy" in your theme, remove it. Add loading="eager" or fetchpriority="high" instead:
<img
src="banner.jpg"
alt="Summer sale banner"
loading="eager"
fetchpriority="high"
/>
fetchpriority="high" tells the browser to prioritize fetching this image over everything else — the most effective way to improve LCP.
For a focused walkthrough including the section.index pattern and <link rel="preload"> in theme.liquid, see Fix Hero Banner Eager Loading in Shopify.
The first product image on collection pages. If your collection page shows product images in a grid, the first row of images is visible immediately. These should not be lazy loaded. Only the images below the fold benefit from lazy loading.
Some themes handle this with conditional logic — only applying loading="lazy" to images after the first few cards.
Impact on Core Web Vitals
Lazy loading correctly implemented improves:
- LCP (Largest Contentful Paint) — by ensuring the hero image loads fast (not lazy loaded) and other resources aren’t competing for bandwidth
- TBT (Total Blocking Time) — by reducing the number of large image downloads happening during page load
It should not significantly change:
- CLS (Cumulative Layout Shift) — ensure images have explicit width and height attributes to reserve space. Without these, lazy-loaded images can cause layout shift when they load.
Related: Add Alt Text to Images in Shopify.
Using srcset for responsive images
Alongside lazy loading, srcset ensures browsers download only the image size appropriate for their screen — not a 2000px image for a 400px product card.
Shopify’s image_tag filter generates srcset automatically. For older img_url usage:
<img
src="{{ product.featured_image | img_url: '400x' }}"
srcset="{{ product.featured_image | img_url: '400x' }} 400w,
{{ product.featured_image | img_url: '800x' }} 800w,
{{ product.featured_image | img_url: '1200x' }} 1200w"
sizes="(max-width: 767px) 100vw, 50vw"
loading="lazy"
alt="{{ product.featured_image.alt }}"
/>
Combined with lazy loading, proper srcset can reduce image data transferred by 40-60% on mobile.
Is lazy loading only for images in Shopify?
No. Lazy loading applies to videos too. Shopify themes can lazy load <video> elements using the loading="lazy" attribute and preload="none", and YouTube/Vimeo embeds can be lazy loaded using a facade pattern (showing a static thumbnail until the user clicks play). For a full walkthrough, see our guide on how to lazy load videos in Shopify. Similarly, iframes (used for embedded maps or forms) can be deferred with loading="lazy". Images remain the highest-impact target since they’re the most common heavy asset on Shopify product and collection pages.
FAQ
Does Shopify lazy-load images by default?
Modern themes (Dawn, Sense, Refresh, Craft and most post-2021 themes) include loading="lazy" by default on collection-page product images, blog featured images, and below-fold sections. Older themes may not. Right-click any image → Inspect → check for loading="lazy" to confirm your theme’s behavior.
Will lazy-loading images hurt my Shopify SEO?
No, when implemented correctly. Google handles lazy-loaded content fine — its crawler triggers viewport scrolls. The SEO win is the speed improvement; lazy-loading reduces initial page weight and improves Core Web Vitals (LCP, TBT). Avoid lazy-loading above-the-fold images, which would worsen LCP.
Why are my lazy-loaded images causing layout shift (CLS)?
Missing width and height attributes. Without explicit dimensions, the browser doesn’t reserve space for the image — when it loads, content jumps. Add width and height attributes (or the aspect-ratio CSS property) on every lazy-loaded image. Shopify’s image_tag filter does this automatically.
Should I lazy-load above-the-fold images?
No. Lazy-loading delays the download until the image is “near the viewport,” which for above-the-fold content is immediate but introduces a slight delay vs. eager loading. The hero/LCP image should always use loading="eager" and fetchpriority="high".
Can I lazy-load CSS background images?
Not via the loading attribute (which only works on <img> and <iframe>). Cleanest fix: describe what you want to Fudge (“convert the hero CSS background to an img tag with native lazy loading”) and it rebuilds the section using a real <img> element. Manual workaround: use Intersection Observer to apply the background-image CSS only when the section enters viewport.
Related: Speed Up a Shopify Theme.