Lazy Loading and What Agents Actually See
Lazy loading defers the loading of images and content until the user scrolls near them. It is a solid performance technique for human visitors, cutting initial page weight and speeding up perceived load times. But agents do not scroll like humans. They load the page, read the DOM, and move on. Content that depends on scroll-triggered loading may never appear.
How lazy loading works
There are two main approaches to lazy loading:
Native lazy loading uses the loading="lazy" attribute on images and iframes:
<img src="product-photo.jpg" loading="lazy" alt="Blue running shoes" />
The browser handles the loading decision based on viewport proximity. Images near the top of the page load immediately. Images further down load when the user scrolls close to them.
JavaScript-based lazy loading replaces src with data-src and uses an Intersection Observer or scroll event listener to swap them when the element enters the viewport:
<img data-src="product-photo.jpg" class="lazy" alt="Blue running shoes" />
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
});
});
document.querySelectorAll('.lazy').forEach(img => observer.observe(img));
</script>
What agents see with each approach
With native lazy loading, the src attribute is present in the HTML. An agent reading the DOM can see the image URL even if the browser has not loaded the image yet. The alt text is also available. The agent gets the information it needs.
With JavaScript-based lazy loading, the src attribute is missing or set to a placeholder (often a tiny transparent GIF or a grey square). The actual image URL is hidden in data-src, which is not a standard attribute. Unless the agent knows to look for this pattern, it sees a page full of placeholder images.
This matters more than you might expect. An agent evaluating product pages needs to know whether images exist and what they show. A page with 12 placeholder images looks broken. A page with 12 properly sourced images with descriptive alt text looks professional and complete.
The content loading problem
Lazy loading is not limited to images. Many sites lazy-load entire content sections:
- Product reviews that load when you scroll past the product description
- Related products that appear at the bottom of the page
- FAQ sections tucked below the fold
- Comments and user-generated content
If an agent does not scroll, it never sees any of this content. From the agent's perspective, the page might contain a product name, a price, and a description, but no reviews, no related products, and no FAQs. That is a significant information gap. This connects directly to the broader issue of client-side rendering hiding content from agents.
Ensuring critical content loads without scroll triggers
Above-the-fold content should never be lazy-loaded. Your primary product image, main heading, price, and call-to-action should load immediately. Use loading="eager" (or simply omit the loading attribute) for these elements.
Use native lazy loading over JavaScript-based approaches. With native loading="lazy", the src attribute is always present in the HTML. Even if the image has not downloaded, agents can see what image was intended and read the alt text.
Include critical data in the initial HTML. If product reviews affect purchasing decisions (and they do), include at least the review summary in the initial server response. You can lazy-load individual review text, but the rating and review count should be present from the start.
Provide structured data regardless of scroll state. Your JSON-LD structured data should include all the important information about the page, whether or not the corresponding HTML has been lazy-loaded. Agents that read JSON-LD get the full picture even when the visible content is incomplete.
Testing for agent visibility
Open your site in a headless browser and read the DOM without scrolling. What do you see? If significant content is missing, agents are seeing the same gaps. You can audit your site for agent readiness to get a complete picture of what is visible and what is hidden behind scroll triggers.
The fix is usually straightforward: move critical content out of lazy-loading wrappers, switch from JavaScript-based to native lazy loading for images, and ensure your structured data covers the full page regardless of viewport position.