Defer Offscreen Images in Magento 2: Complete Lazy Loading Guide

Defer Offscreen Images in Magento 2: Complete Lazy Loading Guide

[Updated: March 19, 2026]

Google PageSpeed Insights flags "Defer offscreen images" on almost every Magento store. The fix is straightforward, but choosing the wrong method wastes time and can hurt your Largest Contentful Paint score.

This guide covers three methods to defer offscreen images in Magento 2, when each method fits, and how to verify results.

Key Takeaways

  • Native loading="lazy" is the simplest method and works without extensions or custom JavaScript

  • The IntersectionObserver API gives fine-grained control for custom themes and complex layouts

  • Third-party extensions add admin panel configuration and advanced features like placeholder images

  • Never lazy load above-the-fold images, hero banners, or your LCP element

  • Core Web Vitals thresholds for 2026: LCP under 2.5 seconds, INP under 200 milliseconds, CLS under 0.1

What Are Offscreen Images?

Offscreen images = Images below the visible viewport that load before the user scrolls to them. They add unnecessary weight to the initial page load, slowing down Time to Interactive and hurting your Core Web Vitals scores.

Perfect for: Magento stores with product catalogs, category pages with 20+ images, CMS pages with media-heavy content

Not ideal for: Pages with fewer than 5 images total, single-product landing pages with all images above the fold

When a browser loads a Magento page, it downloads every image on that page by default. On a category page with 40 product thumbnails, the browser fetches all 40 images even though the visitor sees only 8 to 12 without scrolling.

Google PageSpeed Insights identifies these images and reports the potential savings in kilobytes. The "Defer offscreen images" suggestion means: load images only when they approach the viewport.

Why Deferring Offscreen Images Matters

A one-second delay in page load time can reduce conversions by up to 7%. For Magento stores with hundreds of product images, the impact compounds fast.

Core Web Vitals Impact

Google uses three Core Web Vitals as ranking signals. These thresholds are based on the 75th percentile of real user data from the Chrome User Experience Report (CrUX), not lab tests:

Metric Threshold (Good) How Offscreen Images Affect It
LCP (Largest Contentful Paint) Under 2.5s Competing image requests delay the largest visible element
CLS (Cumulative Layout Shift) Under 0.1 Images without dimensions cause layout shifts as they load
INP (Interaction to Next Paint) Under 200ms Heavy image downloads block the main thread

Only 48% of mobile pages pass all three Core Web Vitals (2025 Web Almanac). Deferring offscreen images is one of the highest-impact fixes.

Bandwidth and Server Load

Every image request hits your server. On a Magento category page, 40 simultaneous image requests during initial load create unnecessary server strain. Lazy loading spreads these requests over time as the user scrolls, reducing peak server load and TTFB.

Method 1: Native HTML loading="lazy" (Recommended)

The simplest approach uses the browser's built-in lazy loading. Add the loading="lazy" attribute to any img tag:

<img src="product-image.jpg"
     loading="lazy"
     width="300"
     height="300"
     alt="Product name">

All major browsers support this attribute: Chrome, Firefox, Safari, and Edge. No JavaScript required. Browsers use adaptive distance thresholds to decide when loading starts: Chromium triggers at 1,250px before the viewport on 4G connections and 2,500px on 3G or slower, so images are ready before the user scrolls to them.

Implementation in Magento 2

In Magento 2.4.x, edit your theme's image templates. The key files:

Category page thumbnails (catalog/product/list.phtml):

<img src="<?= $productImage->getImageUrl() ?>"
     loading="lazy"
     width="<?= $productImage->getWidth() ?>"
     height="<?= $productImage->getHeight() ?>"
     alt="<?= $block->escapeHtmlAttr($productImage->getLabel()) ?>">

CMS blocks and widgets: Add loading="lazy" to img tags in your CMS content through the admin panel or via layout XML overrides.

Page Builder images: Page Builder renders img tags at runtime through its JavaScript templates. To add loading="lazy" to Page Builder images, create a layout XML override or a small custom module that modifies the rendered output.

Critical Rule: Never Lazy Load the LCP Element

The Largest Contentful Paint element is the biggest visible element when the page first loads. On most Magento pages, this is the hero banner or the first product image. Lazy loading your LCP element delays its render and destroys your LCP score.

Use loading="eager" (or omit the attribute) for:

  • Hero banners and sliders
  • First product image on product detail pages
  • Category header images
  • Any image visible without scrolling

Method 2: IntersectionObserver API

For custom Magento themes or complex layouts that need precise control, the IntersectionObserver API detects when elements enter the viewport:

document.addEventListener('DOMContentLoaded', function() {
    const images = document.querySelectorAll('img[data-src]');
    
    const observer = new IntersectionObserver(function(entries) {
        entries.forEach(function(entry) {
            if (entry.isIntersecting) {
                const img = entry.target;
                img.src = img.dataset.src;
                img.removeAttribute('data-src');
                observer.unobserve(img);
            }
        });
    }, {
        rootMargin: '200px 0px'  // Start loading 200px before viewport
    });
    
    images.forEach(function(img) { observer.observe(img); });
});

This method requires changing src to data-src in your image markup and providing a lightweight placeholder. The rootMargin of 200px triggers loading before the image scrolls into view, preventing visible pop-in.

When to Use IntersectionObserver

Scenario Native loading="lazy" IntersectionObserver
Standard product listings Best choice Overkill
Custom AJAX-loaded content Does not work Required
Animated loading effects Not possible Full control
Background images (CSS) Not supported Works with adaptation
Iframes and videos Supported Also works

Method 3: Third-Party Extensions

Extensions provide admin panel configuration without code changes. Here are the main options for Magento 2:

Extension Price Script Type Key Features
Magefan Image Lazy Load Free Multiple JS options Block exclusion, SEO-friendly
WeltPixel Lazy Load Free Native + JS Product and image support, animation effects
Mageplaza Lazy Loading Free Configurable Per-page control, multiple placeholder types
Amasty Lazy Load $259 Advanced Preload first-screen images, threshold config
Plumrocket Lazy Load Free Native Lightweight, minimal configuration

Extension Installation

Install through Composer (standard for all extensions):

composer require vendor/extension-package-name
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:clean

After installation, configure the extension at Stores > Configuration > [Extension Name] > Lazy Load. Set "Enable Lazy Loading" to "Yes" and configure the threshold (distance in pixels before the viewport at which images start loading).

Comparison: Which Method to Choose

Factor Native HTML IntersectionObserver Extension
Setup complexity Low High Medium
Cost Free Free (dev time) Free to $259
Performance overhead Zero Minimal JS Varies by extension
Customization Limited Full control Admin panel options
Browser support All modern browsers All modern browsers Depends on script
Best for Most stores Custom themes Non-technical admins

For most Magento 2 stores, start with native loading="lazy". It has zero performance overhead, no dependencies, and works across all modern browsers. Add an extension only if you need admin-configurable thresholds, placeholder images, or iframe support.

How Server Performance Affects Image Loading

Lazy loading optimizes when images load, but the speed of each image request depends on your server infrastructure. Two stores with identical lazy loading setups will perform differently if one runs on a shared server and the other on managed Magento hosting with dedicated resources.

TTFB and CDN

Time to First Byte determines how fast your server responds to each image request. A server with high TTFB adds delay to every lazy-loaded image as the user scrolls. A Content Delivery Network serves images from edge locations close to your visitors, ensuring that when an offscreen image triggers loading, it arrives from a nearby server rather than your origin.

Image Format Optimization

Before implementing lazy loading, optimize the images themselves. Compress images and serve modern formats like WebP where possible. Lazy loading a 2 MB uncompressed PNG still creates a poor experience when the user scrolls to it.

How to Test and Verify Lazy Loading

After implementation, verify that lazy loading works and improves your scores.

Google PageSpeed Insights

Run your category page URL through PageSpeed Insights. The "Defer offscreen images" warning should disappear or show reduced savings. Check both mobile and desktop scores.

Chrome DevTools Network Tab

  1. Open DevTools (F12) > Network tab
  2. Filter by "Img" type
  3. Reload the page
  4. Scroll down and watch new image requests appear as you scroll

If images load only when you scroll near them, lazy loading works.

Lighthouse Audit

Run a Lighthouse performance audit in Chrome DevTools. Check the "Diagnostics" section for:

  • "Defer offscreen images" (should pass)
  • "Serve images in next-gen formats" (separate optimization)
  • "Image elements have explicit width and height" (prevents CLS)

WebPageTest

For production testing, use WebPageTest with a simulated 4G connection. Compare waterfall charts before and after lazy loading. Look for a shorter initial load waterfall and image requests that appear later in the timeline.

Common Mistakes to Avoid

Lazy loading all images including above-the-fold content. This delays the LCP element and makes the page feel slower. Exclude the first row of products and any hero images.

Missing width and height attributes. Without explicit dimensions, the browser cannot reserve space for lazy-loaded images. As images load during scrolling, content shifts around, increasing your CLS score.

Using JavaScript-only solutions without a fallback. If JavaScript fails to execute, images with data-src instead of src never load. Native loading="lazy" degrades gracefully because the src attribute is always present.

Setting the threshold too low. A threshold of 0px means images load only when they enter the viewport, causing visible pop-in. Set a threshold of at least 200px so images start loading before the user scrolls to them.

FAQ

What does "Defer offscreen images" mean in Google PageSpeed Insights?

It means your page loads images that are not visible in the initial viewport. Google recommends lazy loading these images so they load only when the user scrolls near them, reducing initial page weight and improving load time.

Does Magento 2 support lazy loading natively?

Magento 2.4.x supports the native HTML loading="lazy" attribute. You can add this attribute to image tags in your theme templates without installing any extension. Some Magento themes already include this attribute by default.

Which images should I NOT lazy load?

Never lazy load your hero banner, the first product image on detail pages, category header images, or any image visible without scrolling. These are above-the-fold elements and should load immediately. Lazy loading your LCP element hurts your Core Web Vitals score.

Do I need an extension for lazy loading in Magento 2?

No. The native loading="lazy" attribute handles most use cases without an extension. Extensions add value if you need admin panel configuration, placeholder images, animated loading effects, or support for AJAX-loaded content.

How do I know if lazy loading is working on my site?

Open Chrome DevTools, go to the Network tab, filter by images, and reload your page. Scroll down and watch the network panel. If new image requests appear as you scroll, lazy loading is active.

Will lazy loading affect my SEO?

Lazy loading improves SEO by reducing page load time, which is a Google ranking factor. Googlebot renders JavaScript and recognizes the loading="lazy" attribute, so lazy-loaded images are crawled and indexed. Always include descriptive alt attributes on all images.

What is a good LCP score for a Magento store?

Google considers LCP under 2.5 seconds as "good." For Magento category pages with many images, aim for under 2 seconds. Server response time, image optimization, and lazy loading all contribute to your LCP score.

Can I use lazy loading with a CDN?

Yes. Lazy loading and CDN work together. Lazy loading controls when the browser requests an image, and the CDN ensures that request is served from the nearest edge location. This combination provides the best image loading performance.

What is the IntersectionObserver API?

IntersectionObserver is a JavaScript API that detects when an element enters or exits the browser viewport. It is more efficient than scroll event listeners and gives developers fine-grained control over when lazy-loaded images trigger their actual download.

How much can lazy loading improve my page speed?

Results depend on how many images your page contains. A category page with 40 products can see initial page weight reduced by 60 to 80%. PageSpeed Insights scores improve by 5 to 20 points for image-heavy pages.

CEO & Co-Founder

Raphael Thiel co-founded MGT-Commerce in 2011 together with Stefan Wieczorek and has built it into a leading Magento hosting provider serving 5,000+ customers on AWS. With 25+ years in e-commerce and cloud infrastructure, he oversees hosting architecture for enterprise clients. He also co-founded CloudPanel, an open-source server management platform.


Get the fastest Magento Hosting! Get Started