BlogFindings

Do AI crawlers see lazy loaded images? 3,155 of 51,990 carried no URL in the HTML

Lantad requested the robots.txt and then the home page of all 1,419 hostnames in this repository's committed corpus on 27 September 2026 and read the raw bytes with no JavaScript executed. 1,070 home pages were readable and carried 51,990 image elements. 46,544 of those declared a fetchable URL in src and a further 267 in srcset, leaving 5,179 with neither. 3,155 of the 5,179 carried the real URL in a data attribute a crawler would have to run JavaScript to use.

16 min read Lantad

This run counted both. Lantad asked all 1,419 hostnames in the two committed corpus seed files for /robots.txt, evaluated the site root for its own crawler token before requesting anything else, then requested the home page of every host that allowed it and parsed the bytes with no JavaScript executed. 1,070 answered with HTML and a body. Between them they carried 51,990 image elements, a median of 28 per page. 46,544 of those handed a crawler a URL directly. The interesting number is the 5,179 that did not, and the split inside it, because the two halves of that number call for completely different fixes.

In short

  • Do AI crawlers see lazy loaded images? It depends entirely on which lazy loading a site uses, and on the 1,070 corpus home pages Lantad read on 27 September 2026 the two kinds are not close in size: 27,112 image elements declared the native loading attribute, which costs a crawler nothing, against 3,155 that hid the URL behind a data attribute.
  • Of 51,990 image elements counted on those 1,070 pages, 46,544 carried a fetchable URL in src and 267 more carried one in srcset. 5,179 carried neither, which is 9.96 percent of the images on these pages.
  • 3,155 of the 5,179 carried the real URL in one of seventeen data attributes instead, led by data-src at 4,066 occurrences across all images and data-lazy-src at 1,113. The remaining 2,024 declared no alternative source at all, and 1,753 of those were not inside a picture element either.
  • The concentration matters more than the rate. Only 124 of the 993 pages carrying any image carried a JavaScript-dependent one, and five of the eighteen corpus strata produced zero: Webflow, Framer, single page application startups, static documentation sites and SaaS marketing sites. WordPress small business sites at 18.75 percent and Wix and Squarespace sites at 17.81 percent produced the most.
  • On 17 of the 993 pages not one image declared a src or a srcset, among them ulta.com with 98 image elements, kayak.com with 75 and nationalgeographic.com with 16. Lantad does not score any of this: no part of its composite reads an image element, and its own extractor discards noscript content, so it does not read the fallback images 51 of those 124 pages provide.
StageHostnamesWhat it excludes
Corpus seed files1,419Nothing. Two committed sampling frames.
Returned a robots.txt status1,37445 where the request never produced a status
Allowed LantadBot at the root1,32512 by an explicit rule, 37 by a 5xx treated as disallow
Home page answered 200 with HTML1,070217 that answered 403, 34 other non-200, 2 unusable, 2 with no status
Carried at least one image element99377 pages carrying no img element at all
Carried a JavaScript-dependent image124869 where every image was resolvable from the bytes
One GET of https://<host>/robots.txt, then one GET of https://<host>/, each as LantadBot/1.0 with redirects followed, a fifteen second timeout on robots.txt and twenty on the home page, no JavaScript executed and from one network location. Measured by Lantad on 27 September 2026 across the 1,419 hostnames in worker/seeds/corpus-seeds-platform.json and worker/seeds/corpus-seeds-industry.json.

Two mechanisms with the same name and opposite consequences

The HTML attribute arrived first as a proposal and then as shipped behaviour, and it does the whole job in one word. MDN's reference for the img element, last modified 11 September 2026, defines the two values the loading attribute accepts: eager "Loads the image immediately, regardless of whether or not the image is currently within the visual viewport (this is the default value)", and lazy "Defers loading the image until it reaches a calculated distance from the viewport, as defined by the browser". Nothing about that changes the src attribute. The URL stays in the markup, the browser simply waits before fetching it, and anything reading the bytes gets the address exactly as it would have.

The same page is precise about what identifies an image, and the precision matters for counting: "At least one of src and srcset is required for an img element". That sentence is the whole test applied here. An image element that declares neither a src nor a srcset has not said where it is, and no amount of parsing will recover an address that is not in the document.

The older technique works the other way round. It empties the src, or fills it with a one pixel data URI, and moves the real address into an attribute the platform ignores. Google's own lazy loading guidance for search, carrying Last updated 2025-12-10 UTC, lists browser built-in lazy loading alongside IntersectionObserver and JavaScript libraries as implementation choices and asks only that you "make sure that your lazy-loading implementation loads all relevant content whenever it is visible in the viewport". That is written for a crawler that renders. It is not advice a reader can apply if the thing fetching the page does not run scripts, and only two of nine AI crawler operators say either way whether they render JavaScript.

Google's other property is blunter about whether the library is still needed. web.dev's article on browser-level image lazy loading, last updated 13 August 2024, states that "With full support of lazy loading built into modern browsers, you probably don't need a third-party library or script to lazy-load images", and gives two narrow reasons to keep one: a polyfill for browsers without the attribute, and finer control over the trigger. Two years on, this corpus shows how far that has travelled.

MechanismWhere the URL sitsWhat a JS-blind crawler getsCounted here
Native loading="lazy"src or srcset, unchangedThe real URL27,112 images
Native loading="eager"src or srcset, unchangedThe real URL2,265 images
No loading attributesrc or srcset, unchangedThe real URL22,551 images
Script-driven, data attributedata-src and similarA placeholder or nothing3,155 images
No source declared anywhereNowhere in the markupNothing2,024 images
The two lazy loading mechanisms as the specifications and vendor documentation define them, against what a crawler reading raw bytes receives from each. Definitions from MDN's img reference, last modified 11 September 2026, read 27 September 2026.

Do AI crawlers see lazy loaded images?

Every image element was classified once, on the markup alone. An image counts as resolvable here when its src attribute is present, non-empty and not a data URI, an about:blank or a bare fragment. If the src fails that test the srcset is checked next, because the standard accepts either. Only when both are absent is the element examined for one of seventeen data attributes that lazy loading libraries conventionally use.

46,544 of the 51,990 images passed on src. 267 more passed on srcset. 5,179 failed both, which is 9.96 percent of the image markup on these pages. Of those 5,179, exactly 3,155 carried a non-empty data attribute holding what is almost certainly the address, and 2,024 carried nothing of the kind. So the answer to whether an AI crawler sees a lazy loaded image is that it depends on which mechanism is in front of it, and on this corpus the harmless mechanism is roughly nine times more common than the harmful one: 27,112 images declared loading="lazy" and 25,992 of those also carried a usable src, against 3,155 that made the URL conditional on a script running.

That is a different picture from the one the advice describes, and it is worth saying plainly that it cuts against the alarming version of the story. 657 of the 993 pages carrying any image used the native attribute. Only 124 carried a single JavaScript-dependent image. The rate of native adoption is itself uneven, from 86.6 percent of Webflow images down to 17.0 percent on static documentation sites, but a page that declares nothing at all is no worse off for a crawler than one that declares eager, because in both cases the URL is right there in the src.

What the measurement cannot tell you is whether any of this costs anything. No citation, ranking or retrieval outcome was measured on any of these pages, and no crawler vendor publishes what it does with an image element. This sits beside the earlier finding that 18,171 of 52,077 images carried an empty alt attribute, which is about whether a machine can read what an image contains. This one is about whether it can find the image at all, and the two failures stack: an image with no address and no alt text has told a reader of the bytes nothing whatsoever. Neither failure touches prose parity, which is the one part of the score that compares a rendered page against its raw bytes, because that comparison reads words and an image has none.

The classification applied to each of the 51,990 image elements counted on 1,070 corpus home pages. Lantad, 27 September 2026.

Where the URL goes when the src does not hold it

The seventeen attribute names checked are the ones lazy loading libraries have settled on, and eight of them actually appeared. data-src leads at 4,066 occurrences across all images, followed by data-lazy-src at 1,113, data-srcset at 950, data-image at 734, data-lazy-srcset at 256, data-full-src at 142, data-original at 28 and data-lazy at 21. Those counts run across every image carrying the attribute, including images that also declared a perfectly good src, which is why they exceed the 3,155 figure.

One of the eight deserves a caveat rather than a defence. The test applied is that the attribute exists and is not empty, never that its value parses as a URL, and data-image at 734 occurrences is the one name in the list that could plausibly hold an identifier rather than an address. Take it out entirely and the script-dependent count still stands in the thousands. The other seven are unambiguous lazy loader conventions.

The picture element complicates the count in the publisher's favour and it was allowed to. 6,391 picture elements appeared across these pages holding 14,767 source elements, and 271 of the 2,024 images with no declared source of their own sat inside one, where a sibling source may carry the address. That leaves 1,753 image elements with no src, no srcset, no data attribute and no picture parent: nothing anywhere in the markup that says where the image is. A further 3,288 source elements inside picture blocks carried a data attribute set rather than a real srcset, which is the same technique applied one element up.

There is an old fallback for exactly this problem and a minority still ship it. 3,097 noscript elements appeared across the corpus and 2,243 of them contained an image, holding 2,292 image elements between them. 51 of the 124 pages with a script-dependent image provide such a fallback and 73 do not. The awkward part is ours: Lantad's own extractor discards script, style, noscript, template, svg and iframe content before it reads anything, so those fallback images are invisible to this scanner too, on the same rule that made 834 iframes on 433 home pages invisible to it. That is a defensible choice for measuring prose, since noscript blocks are frequently cookie warnings rather than content, and it was already visible in the finding that fourteen noscript elements held no text. For images it is a gap, and naming it is cheaper than pretending the count is complete.

AttributeOccurrencesReading
data-src4,066The most common spelling in this corpus, by a factor of three
data-lazy-src1,113The second most common spelling
data-srcset950A responsive set deferred the same way
data-image734The one name here that may hold an identifier rather than a URL
data-lazy-srcset256A deferred responsive set, plugin spelling
data-full-src142A full resolution address behind a smaller placeholder
data-original28A rare spelling in this corpus
data-lazy21The rarest spelling found here
Data attributes found holding an image address, counted across all 51,990 image elements on 1,070 corpus home pages, so an image with a usable src that also carries the attribute is included. Lantad, 27 September 2026.

The platform decides this, not the publisher

Split the corpus by how the sites were built and the rate stops looking like a property of care. Five of the eighteen strata produced no script-dependent images at all: Webflow across 42 pages and 2,785 images, Framer across 31 pages, single page application startups across 44, static documentation sites across 31 and SaaS marketing sites across 37. Not a low rate in those five. Zero. At the other end, WordPress small business sites put 18.75 percent of their image markup behind a script, and Wix and Squarespace sites 17.81 percent, with 22 of 54 Wix and Squarespace pages carrying at least one.

The explanation is not mysterious and it is the same one that keeps turning up in this corpus. A hosted builder emits the markup its template generator produces, and the current generation of generators emits the native attribute, whose browser support that same web.dev article puts at Chrome 77, Edge 79, Firefox 75 and Safari 15.4. A site assembled from plugins carries whatever the plugin author wrote, and plugins outlive the problem they were written for. Shopify storefronts sit between the two at 6.97 percent, which is a theme layer emitting the native attribute over an app layer that sometimes does not, and the Shopify stack guide covers what a storefront owner can change and what the theme decides for them. The same split appeared when 0 of 69 Wix robots.txt files named an AI crawler and when 16 of 24 WordPress robots.txt files named none: the platform decides, and the publisher usually does not know there was a decision.

The individual pages behind the rates are worth naming because they are not marginal. technion.ac.il carried 515 image elements of which 257 were script-dependent, visitbritain.org 222 of 409, mekari.com 219 of 439, derstandard.at 168 of 170, maxbone.com 124 and hookagency.com 100 of 105. browserstack.com is the instructive one: it declared loading="lazy" on 172 images and still routed 96 through a data attribute, which is a site that adopted the new mechanism without retiring the old one. Every host named here was re-requested by a second independent request the same day and every one reproduced its counts.

Seventeen pages went further, declaring no src and no srcset on any image at all. ulta.com carried 98 such elements, kayak.com 75, article.com 38, parthenonplumbing.com 22 and inserm.fr 21, with nationalgeographic.com at 16, cshl.edu at 11 and statcan.gc.ca at 3. On those pages a reader of the delivered bytes finds image elements and no images. It is the visual counterpart of the text problem measured when JavaScript supplied all of the prose on 11 of 271 pages, and it tends to arrive from the same architecture.

  • wordpress-smb 18.75%
  • wix-squarespace 17.81%
  • education 13.81%
  • media-local 12.4%
  • bubble-nocode 9.75%
  • travel 8.75%
  • shopify-dtc 6.97%
  • saas 6.93%
  • healthcare 6.73%
  • ecommerce 5.17%
  • news 4.81%
  • finance 4.12%
  • government 1.45%
  • framer 0%
  • webflow 0%
  • spa-startups 0%
  • static-docs 0%
  • saas-marketing 0%
Share of each stratum's image elements whose address was reachable only through a data attribute, so absent from the delivered bytes. Lantad, 1,070 readable home pages, 27 September 2026.

What to check on your own site, and what none of this proves

The check is cheap and needs no tool. Fetch your own page without a browser, search the response for the string data-src, and look at what the src attributes next to it contain. If the src holds a real path and the loading attribute says lazy, there is nothing to fix and never was. If the src is empty or holds a data URI while a data attribute holds the path, every image on that page is conditional on a script that a given crawler may or may not run. Seeing the page as a crawler receives it is the only way to tell the two apart, because in a browser they look identical, which is exactly why this survives on sites whose owners check their work. Which crawlers reach your pages at all is a separate question with its own answer, and the crawler reference lists the tokens worth checking first.

The fix, where there is one, is a deletion rather than an addition. Put the address back in src and add loading="lazy", which is what the native attribute was shipped to replace the library with. It is unusual in this subject for the recommended change to make a page simpler, and it is worth contrasting with the advice that fills most generative engine optimization and answer engine optimization checklists, which asks for more markup rather than less. The same pattern showed up in the count of list markup, where 80,761 of 104,474 list items turned out to be navigation and the useful change was to declare what was already there rather than add more.

Three limits on all of it. This scanner does not score images: no part of its composite reads an image element, and the methodology page is the place that says so, so nothing measured here moves a grade and none of it is a defect in the product's sense. Every figure describes one home page per hostname on one date from one network location, so a gallery three clicks in is invisible here by construction, and 217 of the 1,325 hosts asked answered 403 to a declared crawler and are simply absent from the denominator, which is its own finding and was measured separately when 103 of 1,089 sites served an unknown bot and refused GPTBot. And the corpus is an editorial sampling frame assembled for platform and industry coverage, not a random draw of the web, so every rate here supports a statement about these 1,419 hostnames and nothing wider.

The last limit is the one that constrains the conclusion hardest. Whether an image element matters to an AI crawler at all is not established by anything in this run, and the honest state of the evidence is that no operator publishes what it extracts from one. What can be said is narrower and still worth knowing: on 124 of these pages the address is not in the document, on 17 of them no image address is in the document, and a crawler that does not execute scripts cannot recover an address that was never sent. That is a statement about bytes, which is the only kind of statement this measurement is entitled to make, and the reason AI visibility is measured as access before it is measured as anything else.

  • Every image resolvable 869 pages Each image declares a src or a srcset, whether or not it also declares loading="lazy". Across all 993 pages carrying images, not just these 869, 657 used the native attribute somewhere.
  • Some images script-dependent 124 pages 3,155 image elements between them, addressed only through a data attribute. browserstack.com ran 96 of these alongside 172 native lazy images.
  • A noscript fallback provided 51 of those 124 A duplicate image with a real src inside a noscript element. Lantad's own extractor discards noscript, so it does not read these either.
  • No image address anywhere 17 pages Not one image declared a src or a srcset. Includes ulta.com at 98 image elements, kayak.com at 75 and nationalgeographic.com at 16.
The four arrangements found on the 993 corpus home pages carrying at least one image element, and what each hands a crawler reading the delivered bytes. Lantad, 27 September 2026.

Written by

Lantad

Published .

The advice that lazy loading hides your images from crawlers predates the attribute that made most of it obsolete, and it was true when it was written. It described a specific technique: leave the src attribute empty or pointing at a blank placeholder, put the real URL in a data attribute, and have JavaScript swap them in when the image nears the viewport. A crawler reading the delivered bytes gets the placeholder and nothing else. Since then browsers shipped an attribute that does the same job with no script at all, and the question is no longer whether lazy loading hides images but which lazy loading a site is running.

Common questions

Do AI crawlers see lazy loaded images?

It depends on the mechanism, and on the 1,070 corpus home pages Lantad read on 27 September 2026 the two are not close in frequency. Native lazy loading, the loading="lazy" attribute, leaves the URL in the src where any crawler reading the bytes finds it, and 27,112 image elements used it. Script-driven lazy loading moves the URL into a data attribute, and 3,155 image elements did that, which a crawler recovers only if it executes JavaScript. No citation or retrieval outcome was measured, so nothing here shows what either choice costs.

Does loading="lazy" hurt SEO or AI visibility?

Nothing measured here suggests it does anything at all to what a crawler receives. The attribute defers the browser's fetch and leaves the src attribute untouched, so the address is in the delivered bytes either way. Of the 27,112 image elements declaring it across these pages, 25,992 also carried a usable src, and the remainder failed for a separate reason. web.dev's article on browser-level image lazy loading, last updated 13 August 2024, states that with full support built into modern browsers you probably do not need a third-party library or script to lazy-load images.

How do I tell which kind of lazy loading my site uses?

Fetch the page without a browser and read the raw response rather than the rendered page, because the two look identical on screen. If an image element carries a real path in src, the address is in the document. If src is empty or holds a data URI while data-src, data-lazy-src or data-srcset holds the path, the address is only recoverable by running the script. On this corpus data-src was the most common of the eight attributes found, at 4,066 occurrences.

How many pages send no image address at all?

17 of the 993 corpus home pages carrying at least one image element declared no src and no srcset on any of them, so a reader of the delivered bytes finds image elements and no images. ulta.com carried 98 such elements, kayak.com 75 and nationalgeographic.com 16. A further 2,024 individual image elements across the corpus declared no source and no data attribute either, and 1,753 of those were not inside a picture element that might have supplied one.

See what AI can read on your site

Run a free scan and get a graded report of exactly what AI crawlers can and cannot read, with ranked fixes.