What Shopify Does Natively for Lazy Loading
Shopify doesn't have a single "lazy loading" toggle in your admin panel. There's no checkbox under Settings → Performance that enables it store-wide. Instead, Shopify provides tools for theme developers to implement lazy loading — and whether those tools are used depends entirely on your theme.
Here's what Shopify provides at the platform level:
The image_tag Liquid filter — When themes use this filter to render images, Shopify can automatically set loading="lazy" on images in sections that appear lower on the page.
The section.index property — Tells theme developers the position of a section on the page, allowing conditional logic: eager-load the first 2 sections, lazy-load everything below.
Automatic WebP/AVIF conversion — Shopify's CDN automatically serves images in modern formats when the browser supports them, reducing file sizes by 25–50%.
Responsive image srcset — The image_tag filter generates multiple image sizes so browsers download the right size for each screen.
These are solid building blocks. But they're building blocks — not a complete solution. The gap between "tools available" and "tools actually used in your store" is where most performance problems live.
Curious where your store stands? Run a free speed test to see if lazy loading is helping or hurting your performance.
How Shopify's image_tag and section.index Work
The image_tag Liquid filter is Shopify's recommended way to render images in themes. When a theme developer uses it correctly, it handles responsive sizing, format conversion, and lazy loading in one line:
{{ product.featured_image | image_url: width: 800 | image_tag: loading: "lazy" }}
But the real power comes from combining it with section.index. This property tells the theme which position a section occupies on the page. Shopify's performance team recommends using it like this:
{%- liquid
if section.index > 2
assign loading = "lazy"
else
assign loading = "eager"
endif
-%}
{{ section.settings.image | image_url: width: 1080 | image_tag: loading: loading }} This code eager-loads images in the first two sections (typically hero and featured collection) and lazy-loads everything below. It's a smart approach that avoids the #1 lazy loading mistake — lazy loading your LCP image.
Key detail: The section.index property was only introduced in late 2022. Themes built before this date don't use it, meaning they either lazy load everything (bad for LCP) or nothing (bad for below-fold performance).
The image_tag filter also generates a srcset attribute with multiple image widths, letting the browser pick the optimal size. This works with lazy loading — when the browser decides to load a lazy image, it picks the right size from the srcset based on the viewport width.
Which Shopify Themes Have Native Lazy Loading?
Not all themes are equal when it comes to lazy loading implementation. Here's the breakdown:
Themes With Good Native Lazy Loading
Dawn (and Dawn-based themes) — Uses image_tag + section.index correctly. Also adds fetchpriority="high" on LCP images. This is Shopify's reference implementation and the gold standard for theme performance.
Sense, Craft, Taste, Colorblock — Shopify's own free themes, all built on the Dawn architecture. They inherit the same lazy loading logic.
Most premium themes updated after 2023 — Reputable theme developers like Out of the Sandbox, Archetype, and Prestige have updated their themes to use section.index and image_tag.
Themes With Poor or No Native Lazy Loading
Themes built before 2022 — These pre-date section.index and often use JavaScript lazy loading libraries like lazysizes, or no lazy loading at all.
Heavily customized themes — Even if the base theme had lazy loading, custom modifications often break it. Developers adding custom sections frequently skip the section.index logic.
Themes using JS-only lazy loading — Some themes use lazysizes or similar libraries that add JavaScript overhead and can conflict with native browser lazy loading.
Not sure which category your theme falls into? The easiest way to find out is to inspect your site — which we'll cover in the testing section below. For a deeper look at theme performance, check our guide on the fastest Shopify themes.
5 Things Shopify's Native Lazy Loading Doesn't Cover
Even with a modern theme using image_tag correctly, native Shopify lazy loading has significant blind spots:
1. App-Injected Images and Scripts
Every Shopify app that adds visual elements — review widgets, trust badges, upsell popups, chat widgets — injects its own images and scripts directly into the DOM. These bypass your theme's lazy loading entirely because they're not rendered through Liquid's image_tag.
The average Shopify store has 6–8 apps installed. Each one adds scripts that load immediately, regardless of where they appear on the page. This is the biggest speed killer on most stores — and it's completely outside the scope of native lazy loading.
2. CSS Background Images
The loading="lazy" attribute only works on <img> and <iframe> elements. Images set as CSS backgrounds (background-image: url(...)) — common in hero sections, banners, and section overlays — are always eager-loaded. The browser downloads them as soon as it parses the CSS, even if the section is far below the fold.
3. Videos and Embeds
While loading="lazy" technically works on iframes (including YouTube embeds), Shopify's image_tag filter doesn't apply to video elements or iframes — it's image-only. Merchants adding product videos, YouTube reviews, or Instagram embeds need to handle lazy loading separately.
4. Responsive Loading Decisions
The section.index > 2 approach is a rough heuristic. What's "below the fold" on a desktop monitor is very different from a mobile phone. An image grid that shows 4 columns on desktop (all visible) might show 1 column on mobile (only 1 visible). Native lazy loading doesn't adapt to screen size — it uses the same section-based logic regardless of device.
5. Script Deferral
Lazy loading images is only half the performance equation. Render-blocking scripts — both from your theme and from apps — often cause more performance damage than unoptimized images. Native lazy loading addresses images but does nothing for JavaScript. Deferring app scripts, inlining critical CSS, and preloading fonts require a different toolset entirely.
Fill Every Gap: Thunder Handles What Native Lazy Loading Can't
Thunder Page Speed Optimizer works on top of your theme's native lazy loading — filling every gap listed above. It automatically identifies your LCP image and eager-loads it, lazy loads everything below the fold (including app-injected content), and defers non-critical scripts that image lazy loading can't touch.
- ✦ Defers app scripts — the biggest speed killer that no amount of image lazy loading can fix
- ✦ Intelligent LCP detection — never lazy loads above-fold content, regardless of device
- ✦ Works with any theme — old, new, custom, or out-of-the-box
- ✦ Inlines critical CSS + preloads fonts — comprehensive optimization, not just image loading
Most stores see a 27+ point speed score improvement after installing — because Thunder addresses the full optimization stack, not just image loading. See pricing.
Install Thunder — Free Trial →How to Check If Your Shopify Store Has Lazy Loading
Before making any changes, verify whether your theme already implements lazy loading. Here are three ways to check:
Method 1: Inspect Element (30 Seconds)
- 1. Open your store in Chrome
- 2. Scroll down to an image well below the fold (e.g., a product in the third row of a collection)
- 3. Right-click the image → Inspect
- 4. Look for
loading="lazy"in the<img>tag
If you see loading="lazy", your theme has native lazy loading for that image. If you see loading="eager" or no loading attribute at all, it doesn't.
Method 2: Chrome DevTools Network Tab
- 1. Open DevTools (F12) → Network tab
- 2. Filter by "Img"
- 3. Hard reload (Ctrl+Shift+R)
- 4. Watch the image count — if all images load immediately, lazy loading isn't working
- 5. Now slowly scroll down — if new image requests appear as you scroll, lazy loading is active
Method 3: PageSpeed Insights
Run your store through Google PageSpeed Insights. If you see the "Defer offscreen images" recommendation, your below-fold images aren't being lazy-loaded. If that recommendation doesn't appear, lazy loading is likely working. You can also use our free Shopify speed test for a quick assessment.
Adding Native Lazy Loading to Shopify Manually
If your theme doesn't have lazy loading or implements it poorly, here's how to add it manually. This requires editing your theme's Liquid files — make a backup first.
Step 1: Use image_tag Instead of img Tags
Find instances where your theme uses raw <img> tags and replace them with Shopify's image_tag filter. This alone gives you responsive images, WebP conversion, and the foundation for lazy loading.
Before (manual img tag):
<img src="{{ product.featured_image | image_url: width: 800 }}" alt="{{ product.title }}" /> After (image_tag with lazy loading):
{{ product.featured_image | image_url: width: 800 | image_tag: loading: "lazy", alt: product.title }} Step 2: Add section.index Logic
To avoid lazy loading above-the-fold images, add conditional logic based on section position:
{%- liquid
if section.index > 2
assign loading = "lazy"
else
assign loading = "eager"
endif
-%}
{{ section.settings.image | image_url: width: 1080 | image_tag: loading: loading }} Step 3: Add fetchpriority to Your LCP Image
For your hero image or main product image (the likely LCP element), add fetchpriority="high" to tell the browser to prioritize it:
{{ section.settings.hero_image | image_url: width: 1200 | image_tag: loading: "eager", fetchpriority: "high" }} ⚠️ Important: Only use fetchpriority="high" on 1–2 images per page. Using it on multiple images defeats the purpose — if everything is high priority, nothing is. For LCP optimization strategies, see our dedicated guide.
Common Native Lazy Loading Mistakes on Shopify
❌ Lazy Loading the Hero Image
Adding loading="lazy" to your hero banner or featured product image forces the browser to wait for the IntersectionObserver to confirm it's visible — adding 200–1000ms to your LCP. Shopify's performance team confirmed this costs a median 1.0 second of LCP.
❌ Mixing Native and JS Lazy Loading
Some themes include lazysizes.js and native loading="lazy". This creates double processing: the browser's native lazy loading triggers, and the JS library runs its own intersection logic. It wastes CPU time and can cause images to flash or load twice. Pick one — native is the right choice in 2026.
❌ Missing Width and Height Attributes
Lazy loading without explicit width and height attributes (or CSS aspect-ratio) causes Cumulative Layout Shift (CLS). When the lazy image loads, the page jumps as the image pushes content down. The image_tag filter adds dimensions automatically — another reason to use it instead of raw <img> tags.
❌ Assuming All Sections Use image_tag
Even in themes that generally use image_tag, custom sections and third-party section apps often use raw <img> tags. One improperly loaded section can undermine the entire page's performance. Audit all sections, not just the theme defaults.
These mistakes are exactly why many merchants prefer a comprehensive solution. If you want to understand the full picture of what's slowing your store down, diagnose your store's speed issues with our step-by-step guide, or simply follow the complete optimization guide.
Frequently Asked Questions
Does Shopify automatically lazy load images?
Partially. Shopify's Liquid image_tag filter sets loading='lazy' on images in sections with a section.index greater than 2, meaning the first two sections eager-load while the rest lazy-load. However, this only works in themes that use image_tag correctly — many older and custom themes don't use it at all, so their images load eagerly by default. Thunder Page Speed Optimizer applies intelligent lazy loading across all themes automatically.
Does Dawn theme have lazy loading built in?
Yes. Dawn uses Shopify's image_tag Liquid filter and the section.index property to automatically lazy load images in sections below the second fold. It also uses fetchpriority='high' on LCP images. However, Dawn's implementation doesn't cover dynamically injected images from apps, background images set via CSS, or videos and iframes — all of which benefit from deferred loading.
Do I need a lazy loading app if my theme already has it?
It depends on your theme's implementation quality. If your theme uses Shopify's native image_tag correctly and you have few apps, built-in lazy loading may be sufficient. However, if you use multiple apps (which inject their own images and scripts), have a custom theme, or want comprehensive optimization including script deferral, critical CSS, and font preloading, an app like Thunder provides significantly better results than theme-level lazy loading alone.
What's the difference between Shopify's native lazy loading and browser lazy loading?
Browser lazy loading is the loading='lazy' HTML attribute that tells the browser to defer downloading an image until the user scrolls near it — this works in 96%+ of modern browsers. Shopify's native lazy loading refers to the Liquid image_tag filter that automatically adds this loading='lazy' attribute to images in sections below the fold. They work together: Shopify's Liquid sets the attribute, and the browser implements the actual deferred loading behavior.
Can Shopify's native lazy loading hurt my speed score?
Yes — if the theme applies loading='lazy' to above-the-fold images, it actually delays LCP by adding an unnecessary IntersectionObserver step. Shopify's performance team found that stores lazy loading their LCP image have a median LCP 1.0 second slower than those that eager-load it. Well-implemented themes use section.index to avoid this, but not all themes get it right.
The Bottom Line on Shopify's Native Lazy Loading
Shopify does have native lazy loading — but it's a tool for theme developers, not a store-wide feature. If you're on a modern theme like Dawn that implements image_tag and section.index correctly, your theme images are probably lazy-loaded properly. But that still leaves app-injected content, CSS background images, videos, and — critically — render-blocking scripts completely unaddressed.
For most stores, native lazy loading covers about 30–40% of the optimization opportunity. The rest requires script deferral, image optimization, critical CSS inlining, and intelligent resource prioritization — exactly what Thunder Page Speed Optimizer does automatically.
Start by testing your store: Run a free speed test to see where you stand, then decide whether native lazy loading is enough or if you need a more comprehensive approach.