What Lazy Loading Is and Why It Matters for Shopify Stores

When a customer visits your Shopify store, their browser begins downloading every image on the page immediately — including images that are far below the visible viewport and might never be seen if the user does not scroll. This is the default browser behaviour, and for pages with many product images, it represents a massive waste of bandwidth and a significant contributor to slow load times.

Lazy loading is the technique that changes this behaviour. With lazy loading enabled, images only download when they are about to enter the user’s visible area as they scroll. A product page with twelve images might only download the first two or three on initial load — the ones actually visible above the fold — then load additional images on demand as the user scrolls down.

The speed impact can be dramatic. On a typical Shopify product page, lazy loading can reduce initial page weight by 40–70%, directly improving LCP time and overall PageSpeed score. However, lazy loading is not a “turn it on and forget it” feature. Applied incorrectly, it can actually hurt your performance scores and break your design. This guide explains how to implement it correctly.

The Native Browser Lazy Loading Attribute

Modern browsers support lazy loading natively via the loading="lazy" attribute on <img> tags. This is supported in Chrome, Firefox, Safari (since 15.4), and Edge — covering the vast majority of Shopify store visitors. There is no JavaScript required, no library to install, no performance overhead from the implementation itself.

In Shopify Liquid, adding lazy loading to an image is as simple as including the attribute in your image tag:

<img
  src="{{ product.featured_image | image_url: width: 800 }}"
  loading="lazy"
  width="800"
  height="800"
  alt="{{ product.featured_image.alt | escape }}"
>

Many modern Shopify themes already include loading="lazy" on their image components. However, older themes (pre-2021), heavily customised themes, and some third-party themes do not. Checking your theme’s Liquid files for the presence of this attribute is a quick audit that can identify significant low-hanging fruit.

OneOnic Shopify Experts

Implement Lazy Loading the Right Way — Without Hurting Your LCP

Our Shopify performance team has increased store speed scores by 40+ points for 100+ clients. Get a free speed audit.

Get a Free Speed Audit →

The Critical Mistake: Never Lazy Load Above-the-Fold Images

The most common lazy loading mistake on Shopify stores — and the one that causes the most damage to performance scores — is applying loading="lazy" to images that are visible on page load. This includes your hero banner, the first product image on a product page, and the first images in a collection grid.

When you lazy load an above-the-fold image, you are telling the browser to delay downloading the most important visual element on the page. The browser honours this instruction, waits to start the download, and your Largest Contentful Paint time skyrockets. We have seen stores where a well-intentioned developer added loading="lazy" to all images globally and increased their LCP from 2.8 seconds to 6.2 seconds in the process.

The rule is clear: lazy load images below the fold, eager-load (or explicitly use loading="eager") images above the fold. For your primary LCP image — the hero image or first product image — go further and add fetchpriority="high" to tell the browser this is the highest-priority download on the page.

Identifying Above-Fold vs Below-Fold Images in Shopify Liquid

In Shopify themes, the distinction between above-fold and below-fold images is typically clear:

  • Hero/banner sections — always above the fold on any page. Never lazy load.
  • First product image on a product page — always above the fold. Never lazy load. Add fetchpriority=”high”.
  • Featured collection images (first row) — typically above the fold on desktop, potentially above the fold on mobile. Either eager-load or use no loading attribute (which defaults to eager).
  • Product images in a carousel (after the first) — below the fold until activated. Lazy load.
  • Collection grid images beyond the first row — below the fold. Lazy load.
  • Images in page sections below the hero — typically below the fold. Lazy load.
  • Related products and recently viewed sections — well below the fold. Lazy load.

In your Liquid templates, this often means adding logic to the first instance of an image in a loop to mark it as eager and all subsequent instances as lazy. Shopify Liquid supports forloop.index, which makes this straightforward:

{%- assign loading = 'lazy' -%}
{%- if forloop.index == 1 -%}
  {%- assign loading = 'eager' -%}
{%- endif -%}
<img src="{{ image | image_url: width: 800 }}" loading="{{ loading }}" ...>

Lazy Loading and Cumulative Layout Shift

Lazy loading introduces a CLS risk if not implemented with explicit image dimensions. When an image has no width and height attributes and is being lazy loaded, the browser does not know how much space to reserve for it. When the image loads as the user scrolls, it pushes the page content below it downward — a CLS event that can significantly harm your Core Web Vitals score.

Always pair loading="lazy" with explicit width and height attributes. Shopify’s image objects include the original image dimensions, which you can use in Liquid even if you are serving a resized version:

<img
  src="{{ image | image_url: width: 800 }}"
  loading="lazy"
  width="{{ image.width }}"
  height="{{ image.height }}"
  alt="{{ image.alt | escape }}"
>

The browser uses the width and height attributes to calculate the image’s aspect ratio and reserve the correct space before the image loads, preventing layout shift entirely.

Lazy Loading for Background Images

CSS background images (set via the background-image property) do not support the native loading="lazy" attribute — that only works on <img> tags. However, background images can be lazy loaded using the Intersection Observer API, which allows JavaScript to detect when an element is about to enter the viewport and then set its background image at that point.

For Shopify themes that use CSS background images for section backgrounds or collection banners, implementing Intersection Observer-based lazy loading can meaningfully reduce initial page weight. The pattern involves setting a data attribute with the image URL rather than setting it directly in CSS, then using JavaScript to move the URL into the actual CSS property when the element is near the viewport.

Lazy Loading Videos on Shopify

Product pages and homepage sections increasingly include video content — product demos, brand story videos, lifestyle footage. Video content is heavy, and if videos auto-load on page scroll sections below the fold, they can dramatically increase page weight and consume mobile data allowances.

For <video> elements, use preload="none" for above-fold videos and preload="none" combined with Intersection Observer for below-fold videos. For embedded YouTube or Vimeo videos, use a facade pattern — show a static thumbnail image until the user clicks play, then load the actual embed iframe. This is particularly impactful because YouTube embeds inject significant JavaScript on page load.

How Lazy Loading Interacts with Your Theme’s Image Carousels

Product image carousels — where you swipe through multiple product images — require careful lazy loading implementation. The first image should be eager-loaded. Subsequent images in the carousel are initially off-screen and should be lazy loaded. However, the carousel JavaScript needs to be aware of lazy loading to ensure images load before the user reaches them, not when they are actively trying to view them.

Poor carousel implementations load all images on page load, negating lazy loading benefits. Good implementations trigger loading for the next one or two images in the sequence as the current image becomes active, providing a seamless user experience while minimising initial load weight.

If your theme’s carousel is loading all images upfront, this is a meaningful optimisation opportunity that requires changes to the carousel JavaScript — typically a job for a developer with Shopify theme experience.

Measuring the Impact of Lazy Loading

After implementing lazy loading, measure its impact using PageSpeed Insights and GTmetrix. The metrics to watch are: total page weight on initial load (should decrease), LCP time (should stay the same or improve), and Largest Contentful Paint element (verify it is still being eagerly loaded, not lazy loaded by accident).

Also use the Chrome DevTools Network tab filtered to Images to see which images are loading on initial page load vs loading lazily as you scroll. This gives you a definitive confirmation that lazy loading is working as intended.

Need help implementing lazy loading correctly across your entire Shopify theme without harming your LCP or CLS scores? The performance team at OneOnic handles full lazy loading implementation as part of our speed optimisation engagements. Get a free speed audit to see exactly what opportunities exist on your store, or review our client work to see the kind of results we achieve.

Shopify Experts · OneOnic

Ready to Grow Your Shopify Store?

Our Shopify experts at OneOnic have helped hundreds of brands launch, optimise, and scale.