How to Lazy-Load Images with loading="lazy"
Your audit found images that load immediately even though they sit below the fold. Lazy loading defers those off-screen images until the visitor scrolls near them, cutting initial page weight and speeding up load. The fix is usually one attribute: loading="lazy" on below-the-fold images. Keep it off your hero and LCP image, which should load eagerly.
What this means
This notice means the audit found <img> elements that load immediately, even when they sit far below the fold and the visitor may never scroll to them. Each of those images is fetched during the initial page load, competing for bandwidth with the content the user sees first.
Native lazy loading fixes this with a single HTML attribute: loading="lazy". When it is present, the browser postpones fetching the image until it is about to enter the viewport. This is a built-in browser feature supported in all current browsers (Chrome, Edge, Firefox, Safari), with no JavaScript library required. Iframes support the same attribute.
The codes missing_lazy_load and no_lazy_loading mean the same thing: the checker looked for loading="lazy" on your off-screen images and didn't find it. It is a notice, not an error, because lazy loading is an optimization, not a correctness requirement. The page still works without it. It just downloads more than it needs to up front.
One nuance drives the whole fix: lazy loading is the wrong choice for images in the first screenful, especially your largest visible image (the LCP element). Lazy-load what's off-screen, eagerly load what's on-screen.
Why it matters
Loading every image up front wastes bandwidth on assets the visitor may never see. On an article with 20 inline images or a long product grid, that can mean fetching several megabytes before the browser finishes rendering the top of the page. Deferring off-screen images frees that bandwidth for what actually matters to first paint.
For classic Google ranking, this shows up in Core Web Vitals. Fewer competing image requests can help Largest Contentful Paint (LCP), which should stay under 2.5 seconds, because the browser isn't fetching images the user can't see yet. Lighter pages also reduce total transfer size and improve the experience on slow mobile connections, where much of search traffic lands.
The catch that hurts rankings is lazy-loading the wrong image. If you put loading="lazy" on your hero or LCP image, you delay the one image that decides your LCP score, which can add hundreds of milliseconds. Getting this right means being deliberate about which images get the attribute.
For AI answer engines the effect is indirect but real. Faster, lighter pages are crawled more efficiently, and crawlers that render or fetch pages (GPTBot, PerplexityBot, Google's AI systems) benefit from the smaller payload. More importantly, native loading="lazy" keeps a real src and alt in the HTML, so crawlers still see the image. JavaScript lazy-loaders that swap data-src at runtime can hide images from bots that don't execute scripts, so the native approach is both faster and more machine-readable.
How to fix it
- 1
Add loading="lazy" to below-the-fold images
The core fix is one attribute on off-screen
<img>tags:<img src="photo.jpg" alt="..." loading="lazy">. This tells the browser to defer the download until the image is near the viewport. Apply it to gallery images, blog post inline images, product grids past the first row, footer logos, and anything a visitor has to scroll to reach. No JavaScript or plugin is needed; it is native browser behavior. - 2
Keep your hero and LCP image eager
Leave the first large image the visitor sees loading eagerly.
loading="eager"is the default, so simply omit the attribute (or set it explicitly). Addingloading="lazy"to the LCP image delays your most important paint and measurably worsens Largest Contentful Paint. Rule of thumb: anything in the first screenful stays eager; everything below it getsloading="lazy". - 3
Prioritize the LCP image instead
For the hero image, go the opposite direction and speed it up with
fetchpriority="high":<img src="hero.webp" alt="..." fetchpriority="high" decoding="async">. This tells the browser to fetch it ahead of lower-priority resources. Pairing eager loading on the hero with lazy loading below it reduces bandwidth competition, which often lets the LCP image arrive faster. - 4
Set width and height to prevent layout shift
Lazy-loaded images that pop in later cause Cumulative Layout Shift (CLS) when the browser doesn't know their size in advance. Add explicit
widthandheightattributes (or a CSSaspect-ratio) so the browser reserves space:<img src="photo.jpg" alt="..." loading="lazy" width="800" height="600">. This is a common oversight that turns a performance win into a layout-stability problem. - 5
Use the native attribute, not a JavaScript lazy-loader
Older setups used JS libraries that put the real URL in
data-srcand only setsrcon scroll. Prefer nativeloading="lazy": it is faster, needs no script, and keeps a realsrcin the HTML so crawlers and AI bots can see the image. If a legacy plugin is doingdata-srcswapping, switching to native lazy loading usually improves both performance and crawlability. - 6
Re-run the audit and check real-world metrics
After deploying, re-crawl the page to confirm the notice clears. Then verify you didn't lazy-load the wrong image: run Lighthouse or PageSpeed Insights and watch for a warning that the LCP element was lazily loaded. If you see that warning, remove
loading="lazy"from the flagged image and addfetchpriority="high"instead.
Example
<!-- Above the fold: hero / LCP image. Load eagerly and prioritize it. -->
<img
src="/img/hero.webp"
alt="Team collaborating in an open office"
width="1200"
height="630"
fetchpriority="high"
decoding="async">
<!-- Below the fold: defer until the user scrolls near it. -->
<img
src="/img/feature-1.webp"
alt="Dashboard showing weekly analytics"
width="800"
height="600"
loading="lazy"
decoding="async">
<!-- Iframes support lazy loading too (e.g. embedded video). -->
<iframe
src="https://www.youtube.com/embed/xxxx"
title="Product walkthrough"
width="560"
height="315"
loading="lazy"></iframe>Eager, prioritized hero image at the top; lazy-loaded images below the fold. Note width/height on every image to prevent layout shift.
Platform-specific steps
WordPress adds loading="lazy" to content images automatically since version 5.5. Since 5.9 it also skips the first content image on the page to protect LCP. If images still lack the attribute, a page builder or theme may output raw <img> tags that bypass the filter, or an optimization plugin may have replaced core lazy loading with its own. Check your caching/optimization plugin (WP Rocket, LiteSpeed, Perfmatters) for a lazy-load images setting, enable it, and configure it to exclude above-the-fold images. Yoast and Rank Math do not control lazy loading directly.
Modern themes render images with the image_tag filter, which auto-applies loading="lazy" to images past the first few template sections. To set it explicitly, use the pipeline {{ image | image_url: width: 800 | image_tag: loading: 'lazy' }}, and pass loading: 'eager' for your hero or banner image. If your theme edits image snippets directly (often in snippets/ or within sections), add loading="lazy" to below-the-fold <img> tags and loading="eager" to the hero. Confirm the main hero image is eager.
Both platforms apply lazy loading to their managed images automatically and do not expose the loading attribute for manual editing. If the audit flags images here, it is usually images embedded through custom code or HTML blocks. For any <img> tags you added yourself in an embed, include loading="lazy" manually.
In raw HTML, add loading="lazy" to off-screen <img> tags and set width and height. In Next.js, the next/image component lazy-loads by default; for your hero, set the priority prop (which applies fetchpriority="high" and eager loading) instead of leaving it lazy. In plain React with <img>, add loading="lazy" as a normal attribute; no library needed.
Cloudflare's image features (Polish, Image Resizing) handle format and size, not the loading attribute. Add loading="lazy" in your own markup at the source and let Cloudflare optimize delivery on top of it. Native lazy loading is the recommended path rather than any proxy-level auto-lazy behavior.
Frequently asked
No. Lazy-load only images below the fold. Images visible in the first screenful, especially the largest one (your LCP element), should load eagerly. Applying loading="lazy" to a hero image delays your most important paint and hurts your Largest Contentful Paint score. The rule: eager above the fold, lazy below it.
For images, no. Native browser lazy loading via the loading="lazy" attribute is supported in all current browsers and needs no script. JavaScript libraries were necessary years ago but now add weight and can hide images from crawlers that don't run JavaScript. The native attribute is faster and more SEO-friendly. Iframes support loading="lazy" too.
Native loading="lazy" does not hide images from Google. The image keeps a real src and alt in the HTML, so Googlebot and Google Images can index it. The risk comes from old JavaScript lazy-loaders that store the URL in data-src and only load on scroll, which can prevent crawlers from seeing the image. Use the native attribute to stay safe.
A separate check warns when the LCP image itself was lazy-loaded, because that is a performance mistake. If you added loading="lazy" to every image including the hero, remove it from the hero. That image should load eagerly, ideally with fetchpriority="high". These are two different findings: missing lazy loading on off-screen images, versus wrongly lazy-loading the on-screen LCP image.
It can, if the image has no defined dimensions. When a deferred image loads and pushes content around, it creates Cumulative Layout Shift (CLS). Prevent this by setting width and height attributes on the img tag, or defining an aspect-ratio in CSS, so the browser reserves the correct space before the image arrives.
Does your site have this issue?
Run a free, AI-powered audit and we’ll flag this and 150+ other checks in about a minute. No signup.