/ โ† Image Optimisation Fixes / Lazy Loading
In this guide
  1. How native lazy loading behaves
  2. The two failures the audit reports
  3. The fix, step by step
  4. Before and after markup
  5. Platform notes
  6. Edge cases
  7. Keeping lazy loading correct
  8. Questions and answers

How native lazy loading behaves

Adding loading="lazy" to an img or iframe changes when the browser requests it. Instead of fetching it as soon as the HTML is read, the browser waits until layout is done and the element is within a certain distance of the viewport. As the visitor scrolls, images are requested a little before they come into view so they are usually ready in time.

A few details matter for getting it right:

All current major browsers support the attribute for images. Older browsers simply ignore it and load images normally, so it is safe to use without a fallback.

The two failures the audit reports

FindingWhat it looks likeEffect
Off-screen images loaded eagerlyA long article or product grid requests every image as the page opens.Wasted data for visitors who never scroll, and bandwidth taken away from the first screen.
Main image lazy-loadedThe hero or first product photo has loading="lazy", or a data-src that a script fills in.The image the visitor sees first starts downloading late, which slows Largest Contentful Paint.
Script-based lazy loadingImages start as a placeholder or blank GIF and a JavaScript library swaps in the real address.Nothing loads until the script runs, and the real address is hidden from the browser's preload scanner.

The first is a waste problem. The second and third are speed problems for the part of the page that matters most. A single page can have all three, typically when a theme lazy-loads everything with a script and a page builder then adds eager images further down.

๐Ÿ’ก In Chrome developer tools, the Network panel's Initiator and Priority columns help here. Right-click the column headers to add Priority. Lazy images that are needed immediately show up late in the waterfall with a Low priority, while the main image should appear early with High.

The fix, step by step

Step 1

Record what loads before any scrolling

Open the page in a private window with developer tools, disable the cache, filter the Network panel to images and reload without touching the scroll bar. Every image listed was requested at page load. Repeat with device emulation at a phone width, because far more of the page is off-screen on a phone. Compare the list with what is actually visible on the first screen, and note the file names that load even though they sit well below it.

Step 2

Sort images into first-screen and later

For each template, decide which images are visible without scrolling on common phone and desktop sizes. Usually that is the logo, the hero or first product photo, and perhaps the first row of a grid. Everything else is later. Where an image is on screen for desktop but not phones, treat it as first-screen; loading one image eagerly costs little, while lazy-loading a visible image delays it. Find the Largest Contentful Paint element with PageSpeed Insights as well.

Step 3

Take lazy loading off first-screen images

Remove loading="lazy" from every first-screen image, or set loading="eager" where a platform adds lazy by default. On the single most important image, usually the Largest Contentful Paint element, add fetchpriority="high" so the browser requests it ahead of other files. Do not add high priority to several images, because priorities only help when they single something out. Make sure that main image is a normal img in the HTML, not injected later by a script.

Step 4

Add loading="lazy" to everything further down

In the templates and components that output images below the first screen, add loading="lazy" and decoding="async", and make sure width and height are present so the space is reserved. Good candidates are article body images after the first, product grids beyond the first row, related items, review photos, footer logos and embedded maps or videos in iframes. In a loop, a simple rule works well: the first two or three items eager, the rest lazy.

Step 5

Replace script-based lazy loading with the native attribute

If your images use data-src or data-srcset with a class such as lazyload, move the real addresses back into src and srcset, add loading="lazy" where appropriate, and remove the library and its placeholder images. Search templates for data-src to find every instance. Keep any matching noscript fallback only until the change is live, then delete it, because it is no longer needed.

Step 6

Handle carousels, tabs and hidden images

Images inside sliders, tabs, accordions and menus are often off-screen or hidden even though they sit near the top of the HTML. Keep the first visible slide eager and give the others loading="lazy"; the browser will fetch them as they come near the viewport. Images inside an element set to display: none are not fetched while lazy, which is what you want for a closed accordion, but check they appear promptly once opened.

Step 7

Confirm images still reach search engines

Run the URL Inspection tool in Search Console on a changed page, view the tested page's HTML and screenshot, and confirm the real image addresses are present in src or srcset. Googlebot renders pages with a tall viewport rather than scrolling, so native lazy images are found, but images that only appear after scroll events or clicks may not be. Then run the Image Optimisation audit and PageSpeed Insights again to compare.

Before and after markup

The examples are from a fictional outdoor clothing shop, Fellside Outfitters.

Top of a category page

<!-- Before: theme lazy-loads the banner with a script -->
<img class="lazyload" src="/img/blank.gif"
     data-src="/img/autumn-banner-1600.webp" alt="">

<!-- After: real address in the HTML, requested first -->
<img src="/img/autumn-banner-1600.webp"
     srcset="/img/autumn-banner-800.webp 800w,
             /img/autumn-banner-1600.webp 1600w"
     sizes="100vw" width="1600" height="600"
     fetchpriority="high" alt="">

A product grid loop

{% for product in products %}
  <img src="{{ product.image_640 }}"
       width="640" height="800"
       alt="{{ product.image_alt }}"
       {% if loop.index > 4 %}loading="lazy" decoding="async"{% endif %}>
{% endfor %}

The first four products, which fill the first row on desktop and the first screen on most phones, load immediately. The rest wait. Adjust the number to match your grid.

An embedded map and video

<iframe src="https://www.example.com/embed/map?store=keswick"
        width="600" height="400" loading="lazy"
        title="Map showing the Keswick shop"></iframe>

Third-party embeds are among the heaviest things on a page because they load their own scripts and styles. Lazy-loading the iframe keeps all of that off the initial load when the embed sits below the first screen. For video embeds, a lighter approach is a thumbnail image with a play button that loads the real player only when clicked.

Platform notes

WordPress

WordPress core adds loading="lazy" to images automatically and, in recent versions, tries to leave the first content images eager and to mark the likely main image with fetchpriority="high". Its guess depends on the theme outputting images through core functions. Problems arise when an optimisation plugin also lazy-loads with a script, producing two systems at once, or when a page builder hero is not recognised. Turn off one of the two lazy-load systems, and exclude the hero by class in the plugin's settings.

Shopify

The image_tag Liquid filter accepts a loading parameter, and many current themes set it to lazy for all but the first section. Older themes often ship lazysizes; check the theme's JavaScript assets and data-src attributes before assuming native loading is in place.

Next.js

The Next.js Image component lazy-loads by default. The main image needs to be marked as a priority, as described in our Next.js images guide.

Page builders and sliders

Many slider plugins and page builders have their own lazy-load switches that act independently of the platform's. Look for them in the widget or slider settings when an image stays lazy after you have changed the theme.

Edge cases

โš ๏ธ Adding loading="lazy" to every image by a blanket rule in a template is the most common way the main image ends up lazy. Put the rule in the loop or component with an explicit exception for first-screen positions.

Keeping lazy loading correct

Questions and answers

1. Should I lazy-load all the images on my page?

No. Lazy-load images that start below the first screen, and load everything visible on arrival normally. Lazy-loading a visible image makes the browser wait for layout before requesting it, which slows the moment the page looks complete. The main image at the top, usually the Largest Contentful Paint element, should never be lazy and benefits from fetchpriority set to high. A simple rule in loops, such as eager for the first few items and lazy for the rest, works well.

2. Does lazy loading hurt SEO?

Native lazy loading with the loading attribute does not, because the real image address is in the HTML and Googlebot renders pages with a tall viewport so lazy images are fetched. Problems come from script-based methods that keep the real address in a data attribute and only swap it in after a scroll event or click, which a crawler may never trigger. Check a changed page with Search Console's URL Inspection tool and confirm the images appear in the rendered HTML.

3. What is the difference between loading lazy and fetchpriority?

They control different things. The loading attribute decides whether the browser waits until an image is near the viewport before requesting it. Fetchpriority changes how important a request is relative to others once it is made. Use loading lazy for images further down the page, and fetchpriority high on the single most important image at the top. Using both on the same image is contradictory, because a lazy image still waits for layout however high its priority.

4. Why are my lazy-loaded images loading straight away?

Browsers start fetching lazy images some distance before they reach the viewport, so on a short page most of them may load immediately, which is expected. Other causes are images with no width and height, which collapse to nothing and all fall within range, a hidden carousel whose slides sit side by side in the layout, or a script that forces loading. Add dimensions and test on a long page in a phone-sized window.

5. Should I remove lazysizes or other lazy-load libraries?

In most cases, yes. They were needed before browsers supported the loading attribute, but now they add a script download, hide real image addresses from the browser's early scanner and delay images until the script runs. Move the addresses back into src and srcset, add the native attribute where appropriate and remove the library. Keep a script only for special cases native loading cannot cover, such as heavy CSS backgrounds far down a page.

6. Can I lazy-load iframes and videos too?

Iframes support the same loading attribute, and it is one of the most effective places to use it, because embedded maps, videos and social posts pull in their own scripts and styles. The video element does not support it, but setting preload to none or metadata on videos below the first screen has a similar effect. For YouTube and similar embeds, a thumbnail that loads the player only on click saves even more.

7. Does lazy loading affect Core Web Vitals?

It can help or hurt. Correctly used, it frees bandwidth for the first screen, which can help Largest Contentful Paint on image-heavy pages. Applied to the main image, it delays that image and makes Largest Contentful Paint worse. Lazy images without width and height can also cause layout shift when they appear. It has little direct effect on Interaction to Next Paint, though removing a heavy lazy-load script reduces main-thread work.

Check which of your images load too early or too late

The Image Optimisation audit checks every image on your page for file size, format, dimensions, alt text, lazy-loading, layout shift and CDN delivery, and ranks its recommendations by their effect on loading and bandwidth.

Open Image Optimisation Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Image Optimisation Fixes  ·  Fixing Slow Largest Contentful Paint  ·  Fixing Wrong Image Dimensions  ·  Fixing Decorative Images  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.