---
title: "Lazy loading for SEO: images, video, and crawl tests."
description: "Lazy-load your off-screen media without hiding content. Keep real image sources and paginated links, protect Core Web Vitals, and test rendered HTML."
canonical: "https://scalewithsearch.com/articles/lazy-loading-seo-implementation"
date: "2026-03-20"
modified: "2026-09-25"
---
## Site navigation

- [Scale With Search](https://scalewithsearch.com/)
- Real estate
  - Real estate
    - [Real estate](https://scalewithsearch.com/for/real-estate)
- Work
  - Start here
    - [Send your brief](https://scalewithsearch.com/work#send-your-brief)
    - [Prepare your six-question brief](https://scalewithsearch.com/work#prepare-your-six-question-brief)
  - Build
    - [Site build, content library with SEO, signal desk](https://scalewithsearch.com/work)
- For your business
  - Trades and home services
    - [Auto body and collision shops](https://scalewithsearch.com/for/auto-body-and-collision-shops)
    - [Foundation and home repair contractors](https://scalewithsearch.com/for/foundation-and-home-repair)
    - [Garage door and fencing contractors](https://scalewithsearch.com/for/garage-door-and-fencing-contractors)
    - [HVAC contractors](https://scalewithsearch.com/for/hvac-contractors)
    - [Janitorial and commercial cleaning companies](https://scalewithsearch.com/for/janitorial-and-commercial-cleaning)
    - [Locksmiths](https://scalewithsearch.com/for/locksmiths)
    - [Moving companies](https://scalewithsearch.com/for/moving-companies)
    - [Pest control companies](https://scalewithsearch.com/for/pest-control-companies)
    - [Plumbing and electrical contractors](https://scalewithsearch.com/for/plumbing-and-electrical-contractors)
    - [Restoration and water or fire damage companies](https://scalewithsearch.com/for/restoration-and-water-fire-damage)
    - [Roofing companies](https://scalewithsearch.com/for/roofing-companies)
    - [Towing companies](https://scalewithsearch.com/for/towing-companies)
    - [Tree services and landscaping companies](https://scalewithsearch.com/for/tree-services-and-landscaping)
    - [Solar installers](https://scalewithsearch.com/for/solar-installation)
    - [General contractors](https://scalewithsearch.com/for/general-contractors-and-construction)
    - [Paving, concrete, and flooring contractors](https://scalewithsearch.com/for/paving)
  - Practices and professional services
    - [Bookkeeping and tax practices](https://scalewithsearch.com/for/bookkeeping-and-tax-practices)
    - [Dental practices](https://scalewithsearch.com/for/dental-practices)
    - [Family and criminal defense law firms](https://scalewithsearch.com/for/family-and-criminal-defense-law-firms)
    - [Med spas and aesthetics practices](https://scalewithsearch.com/for/med-spas-and-aesthetics)
    - [Personal injury law firms](https://scalewithsearch.com/for/personal-injury-law-firms)
    - [Veterinary clinics](https://scalewithsearch.com/for/veterinary-clinics)
    - [Gyms and fitness studios](https://scalewithsearch.com/for/fitness)
    - [Therapy and outpatient health practices](https://scalewithsearch.com/for/therapy-and-outpatient-health)
    - [Medical billing companies](https://scalewithsearch.com/for/medical-billing)
    - [Insurance agencies](https://scalewithsearch.com/for/insurance-agencies)
    - [Financial advisors](https://scalewithsearch.com/for/financial-advisors)
    - [Property management companies](https://scalewithsearch.com/for/property-management)
    - [Recruiting and staffing agencies](https://scalewithsearch.com/for/recruiting-and-staffing)
    - [Architects and interior designers](https://scalewithsearch.com/for/architects-and-interior-designers)
    - [Logistics and supply chain companies](https://scalewithsearch.com/for/logistics-and-supply-chain)
  - Agencies, MSPs, and manufacturing
    - [IT and managed service providers](https://scalewithsearch.com/for/it-and-managed-service-providers)
    - [Machine shops and precision manufacturers](https://scalewithsearch.com/for/machine-shops-and-precision-manufacturing)
    - [Marketing agencies and freelancers](https://scalewithsearch.com/for/marketing-agencies-and-freelancers)
    - [SEO agencies and consultants](https://scalewithsearch.com/for/seo-agencies-and-consultants)
    - [Small manufacturers and fabricators](https://scalewithsearch.com/for/small-manufacturers-and-fabricators)
  - Restaurants, shops, studios, and nonprofits
    - [Restaurants and hospitality businesses](https://scalewithsearch.com/for/restaurants-and-hospitality)
    - [Retail stores and ecommerce sellers](https://scalewithsearch.com/for/retail-and-ecommerce)
    - [Photographers, event planners, and travel agents](https://scalewithsearch.com/for/photographers)
    - [Churches and nonprofits](https://scalewithsearch.com/for/churches-and-nonprofits)
  - [All industries](https://scalewithsearch.com/for/)
- Learn
  - For your office
    - [Office job guides](https://scalewithsearch.com/guides/)
    - [Browser calculators](https://scalewithsearch.com/tools/)
  - Start here
    - [How it works](https://scalewithsearch.com/how-it-works)
    - [Free Starter Kit](https://scalewithsearch.com/kit/business-memory-starter-kit.zip)
    - [Synthetic specimen](https://scalewithsearch.com/specimen/working-session-specimen.zip)
  - Guides
    - [The Complete Guide to Business Memory for AI Agents](https://scalewithsearch.com/articles/business-memory-for-ai-agents-guide)
    - [The Complete Small-Business Guide to AI Agent Governance](https://scalewithsearch.com/articles/ai-agent-governance-guide-small-business)
    - [The Complete Guide to Leaving Vendor AI Memory](https://scalewithsearch.com/articles/leaving-vendor-ai-memory-guide)
  - Articles by cluster
    - [Business memory](https://scalewithsearch.com/articles/business-memory-for-ai-agents-guide)
    - [Agent governance](https://scalewithsearch.com/articles/ai-agent-governance-guide-small-business)
    - [Migration and ownership](https://scalewithsearch.com/articles/leaving-vendor-ai-memory-guide)
  - For machines
    - [llms.txt](https://scalewithsearch.com/llms.txt)
    - [llms-full.txt](https://scalewithsearch.com/llms-full.txt)
    - [Machine view](https://scalewithsearch.com/?view=machine)
- Company
  - Evidence
    - [Proof](https://scalewithsearch.com/proof)
  - Company
    - [About](https://scalewithsearch.com/about)

# Lazy-load images, video, and content without hiding them from Google.

A product page carries forty images, two video embeds, and a review list. The browser fetches all of it before the reader sees the first screen. The page is slow, so a developer adds a lazy-loading script. Two weeks later, the product images drop out of Google Images.

Lazy loading delays off-screen resources until the reader scrolls near them. It reduces the initial page weight and can improve load time. The method you choose decides whether Googlebot still sees the resource. This guide covers images, iframes, self-hosted video, and dynamic lists, with a test for each.

## Know what lazy loading changes

Page speed affects rankings and conversion. Google measures page experience with Core Web Vitals: Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP). INP replaced First Input Delay (FID) as a Core Web Vital in March 2024. The [Core Web Vitals developer guide](/articles/core-web-vitals-developer-guide) covers each metric in depth.

Lazy loading helps in three ways:

- It reduces the initial payload, because the browser fetches only the resources near the first screen.
- It can improve LCP, because fewer requests compete for bandwidth with the largest visible element.
- It saves bandwidth for readers who never scroll, which matters most on mobile connections.

The saving depends on how much of the page weight sits below the fold. Measure it on your own page in the browser Network panel before and after the change.

The risk is indexation. If a lazy-loading method hides a resource from Googlebot, Google does not index it. An image that exists only in a `data-src` attribute can disappear from Google Images.

## Understand the crawl limits

Googlebot renders JavaScript and supports lazy loading. It still has limits:

- **Rendering resources.** Google allocates finite resources to JavaScript rendering. A complex lazy-loading script may not run to completion.
- **Infinite scroll.** A page that loads content without end has no bottom for the crawler to reach.
- **JavaScript dependency.** A script-based method assumes that Googlebot runs the script. If the script fails or times out, the content stays hidden.
- **Delayed rendering.** Google can index the initial HTML first and render the page later. The delay can be days.

For the rendering pipeline itself, read [how Googlebot renders JavaScript](/articles/googlebot-javascript-rendering).

## Use native lazy loading first

Native lazy loading uses the HTML `loading="lazy"` attribute. All modern browsers support it, and Googlebot reads it.

### Images

Add `loading="lazy"` to each image below the fold:

```html
<img src="image.jpg" alt="description" loading="lazy" width="800" height="600">
```

The browser defers the fetch until the image is a set distance from the viewport. The browser chooses that distance. Googlebot reads the `src` attribute directly, so the image gets indexed as normal.

Apply three rules:

1. Do not lazy-load an image that is visible on page load. Use `loading="eager"` or omit the attribute.
2. Set `width` and `height` on every image, or set a CSS `aspect-ratio`. Missing dimensions cause layout shift.
3. Combine lazy loading with `srcset` so each device gets an image of the correct size.

```html
<img src="hero.jpg" alt="Hero image" loading="eager" width="1200" height="600">

<img
  src="image-800.jpg"
  srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
  sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
  alt="Product photo"
  loading="lazy"
  width="800"
  height="600">
```

The [image optimization guide](/articles/image-optimization-ux-seo) covers formats, compression, and alt text for the same images.

### Iframes

Third-party embeds, such as YouTube videos and social widgets, accept the same attribute:

```html
<iframe src="https://www.youtube.com/embed/VIDEO_ID" loading="lazy" width="560" height="315"></iframe>
```

Googlebot reads the `src` attribute, so Google still associates the video URL with your page. The performance gain is large. Each third-party iframe loads its own JavaScript and CSS, often 500 KB or more before the reader presses play.

## Add a fallback when you use JavaScript

Some older browsers lack native lazy loading. A JavaScript method can fill that gap. It carries the highest SEO risk of any method in this guide.

### Intersection Observer

The Intersection Observer API detects when an element enters the viewport. The usual pattern puts the image URL in `data-src` and copies it to `src` on entry.

```html
<img data-src="image.jpg" alt="description" class="lazy" width="800" height="600">
```

```javascript
document.addEventListener("DOMContentLoaded", function() {
  const lazyImages = document.querySelectorAll("img.lazy");

  const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.classList.remove("lazy");
        observer.unobserve(img);
      }
    });
  });

  lazyImages.forEach(image => imageObserver.observe(image));
});
```

Before the script runs, Googlebot sees an `img` element with no `src` attribute. The image may not get indexed. Add a `noscript` fallback that carries a real `src`:

```html
<img data-src="image.jpg" alt="description" class="lazy" width="800" height="600">
<noscript>
  <img src="image.jpg" alt="description" width="800" height="600">
</noscript>
```

### Libraries

Three common libraries do the same job:

- **LazySizes** uses native lazy loading where it exists and falls back to a script elsewhere. Load `lazysizes.min.js` with the `async` attribute, then mark images with `class="lazyload"` and `data-src`.
- **Vanilla-Lazyload** is plain JavaScript with no dependencies.
- **Lozad.js** is a small wrapper around Intersection Observer.

Every one of them needs the `noscript` fallback for SEO safety.

## Defer video without losing it

Video is the heaviest resource on most pages. A single file can weigh 10 to 50 MB.

For YouTube and Vimeo, use native iframe lazy loading, as shown above. The browser then defers the player script and the preview image until the reader scrolls to it.

For self-hosted video, show a poster image and load the video on click:

```html
<div class="video-container" data-video-src="video.mp4">
  <img src="poster.jpg" alt="Video preview" class="video-poster">
  <button class="play-button">Play</button>
</div>
```

```javascript
document.querySelectorAll('.video-container').forEach(container => {
  container.addEventListener('click', function() {
    const videoSrc = this.dataset.videoSrc;
    this.innerHTML = `<video controls autoplay><source src="${videoSrc}" type="video/mp4"></video>`;
  });
});
```

Googlebot indexes the poster image. To connect the video itself to the page, add `VideoObject` structured data. Put this object in a `script` element of type `application/ld+json`:

```json
{
  "@context": "https://schema.org",
  "@type": "VideoObject",
  "name": "Video Title",
  "description": "Video description",
  "thumbnailUrl": "https://example.com/poster.jpg",
  "uploadDate": "2026-02-08",
  "contentUrl": "https://example.com/video.mp4"
}
```

For video rich results beyond this markup, see [video SEO and search features](/articles/video-seo-search-features).

## Give dynamic content a crawlable URL

Infinite scroll and "Load more" buttons defer text and product lists, not only media. Each loaded section needs its own URL, or Googlebot cannot reach it.

### Infinite scroll

Infinite scroll loads new items as the reader scrolls. It removes discrete pages, so the crawler has no "next page" to follow. Apply four rules:

1. Give each section a paginated URL, such as `/blog?page=2` or `/blog/page/2/`.
2. Update the address bar with the History API as each section loads.
3. Offer a paginated archive or a "View all" page that works without scroll.
4. Link each paginated page to the next one with an ordinary `a` element.

```javascript
window.history.pushState({}, '', '/blog?page=2');
```

You can also add `rel="prev"` and `rel="next"` link elements:

```html
<link rel="prev" href="https://example.com/blog?page=1">
<link rel="next" href="https://example.com/blog?page=3">
```

Google stated in March 2019 that it no longer uses these link elements as an indexing signal. Other search engines and browsers can still read them. The crawlable `a` links do the work for Google.

### "Load more" buttons

A "Load more" button reveals content on click. It is safer than infinite scroll, because the load is explicit. Googlebot does not click buttons, so it can still miss the content.

```html
<div id="content-container"></div>
<button id="load-more">Load More</button>
```

```javascript
document.getElementById('load-more').addEventListener('click', function() {
  fetch('/api/more-content')
    .then(response => response.text())
    .then(html => {
      document.getElementById('content-container').insertAdjacentHTML('beforeend', html);
    });
});
```

Give the same content a paginated URL, such as `/page/2/`, that loads without interaction. Then add a plain link to it:

```html
<noscript>
  <a href="/blog?page=2">Load More Content</a>
</noscript>
```

Some guides suggest that you detect Googlebot and serve it pre-rendered HTML. Google now describes that pattern, dynamic rendering, as a workaround and not a long-term fix. Prefer server-side rendering or static pagination.

## Protect Core Web Vitals

Lazy loading moves all three Core Web Vitals, in either direction.

**LCP.** LCP measures when the largest visible element renders. If you lazy-load that element, you delay it. Never lazy-load the hero image, the banner, or any image visible on page load.

```html
<!-- Bad: delays the LCP element -->
<img src="hero.jpg" loading="lazy" alt="Hero image">

<!-- Good -->
<img src="hero.jpg" loading="eager" alt="Hero image" width="1200" height="600">
```

**CLS.** CLS measures unexpected layout movement. An image without dimensions pushes content down when it loads. Set `width` and `height`, or reserve the space in CSS:

```css
img {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}
```

**INP.** INP measures how fast the page responds to a click, tap, or key press. A heavy lazy-loading library can block the main thread and slow that response. Prefer native lazy loading. If you need a library, load it with `async`. Do not load it synchronously in the `head`.

Google uses Core Web Vitals as a page experience signal. A faster page also keeps more readers on it.

## Test that Googlebot still sees the content

Run four checks after each lazy-loading change.

**URL Inspection in Google Search Console:**

1. Enter the URL of a page with lazy-loaded images.
2. Click `Test live URL`.
3. Open the screenshot and the rendered HTML.
4. Confirm that each image appears with a real `src`.

**Screaming Frog SEO Spider:**

1. Set rendering to JavaScript under Configuration, Spider, Rendering.
2. Crawl the site.
3. Open the Images report.
4. Confirm that lazy-loaded images appear with valid `src` attributes.

**Rich Results Test.** Google retired the Mobile-Friendly Test in December 2023. The Rich Results Test at `https://search.google.com/test/rich-results` still shows a rendered screenshot and the rendered HTML for a public URL.

**Manual check:**

1. Disable JavaScript in your browser.
2. Load each page type that uses lazy loading.
3. Confirm that critical images and text appear through the `noscript` fallbacks.

## Avoid the common mistakes

Five mistakes cause most lazy-loading damage:

| Mistake | Effect | Fix |
|---|---|---|
| Lazy-load an image above the fold | LCP gets worse | Use `loading="eager"` on visible images |
| Use `data-src` with no `noscript` fallback | Google may not index the image | Add a `noscript` image with a real `src` |
| Omit `width` and `height` | CLS gets worse | Set dimensions or `aspect-ratio` |
| Load text with no URL structure | Crawlers cannot reach the content | Add paginated URLs and plain links |
| Lazy-load every image, small ones included | Script overhead for no gain | Lazy-load only images below the fold |

The best default for SEO is native lazy loading with `loading="lazy"`. It needs no JavaScript, Googlebot reads it, and every modern browser supports it. Use a script only when you need a behavior the attribute cannot give. Pair every script with a crawlable fallback.

----

```text
                  .|########||.                                       .|########||.                                       .|########||.
               |##||.      .||##|.                                 |##||.      .||##|.                                 |##||.      .||##|.
             |#|.              .|#|.                             |#|.              .|#|.                             |#|.              .|#|.
           |#|                    |#|                          |#|                    |#|                          |#|                    |#|
         .#|                        |#.                      .#|                        |#.                      .#|                        |#.
        .#.                          .#|                    .#.                          .#|                    .#.                          .#|
       |#.                            .#|                  |#.                            .#|                  |#.                            .#|
      |#             ......             #|                |#             ......             #|                |#             ......             #|
     .#           ||#########|           #|              .#           ||#########|           #|              .#           ||#########|           #|
    .#.         |######||######|.        .#.            .#.         |######||######|.        .#.            .#.         |######||######|.        .#.
    #.        .##|###|##|#|######|        .#            #.        .##|###|##|#|######|        .#            #.        .##|###|##|#|######|        .#
   ||        |##|#||||||||||||#||#|        ||          ||        |##|#||||||||||||#||#|        ||          ||        |##|#||||||||||||#||#|        ||
   #        |#||||||||||||||||||||#|        #.         #        |#||||||||||||||||||||#|        #.         #        |#||||||||||||||||||||#|        #.
  ||       |#||||||||||||||||||||||#|       ||        ||       |#||||||||||||||||||||||#|       ||        ||       |#||||||||||||||||||||||#|       ||
  #       .#||||||||||||||||||||||||#|       #        #       .#||||||||||||||||||||||||#|       #        #       .#||||||||||||||||||||||||#|       #
 ||   ....|||#||||||##|#|||#|#||##||||....|. ||      ||   ....|||#||||||##|#|||#|#||##||||....|. ||      ||   ....|||#||||||##|#|||#|#||##||||....|. ||
 #.  .  ....|#  ....#|||   ||| .#|||  ....#. .#      #.  .  ....|#  ....#|||   ||| .#|||  ....#. .#      #.  .  ....|#  ....#|||   ||| .#|||  ....#. .#
 #   .  ||||#| .#####||  . .#| .#|||  ||||#   #.     #   .  ||||#| .#####||  . .#| .#|||  ||||#   #.     #   .  ||||#| .#####||  . .#| .#|||  ||||#   #.
.|   |||||  #. |#|||||. ||  #. |#||. .|||||   ||    .|   |||||  #. |#|||||. ||  #. |#||. .|||||   ||    .|   |||||  #. |#|||||. ||  #. |#||. .|||||   ||
||   |....  #. ....|#.      |. ...|. ....||   ||    ||   |....  #. ....|#.      |. ...|. ....||   ||    ||   |....  #. ....|#.      |. ...|. ....||   ||
#.  .||||||##||||||##||####|||||||#||||||#|   .#    #.  .||||||##||||||##||####|||||||#||||||#|   .#    #.  .||||||##||||||##||####|||||||#||||||#|   .#
#    .||####|###########################|.     #    #    .||####|###########################|.     #    #    .||####|###########################|.     #
#      .#||||||.#.|| # |. ..# #| #|||||#|      #    #      .#||||||.#.|| # |. ..# #| #|||||#|      #    #      .#||||||.#.|| # |. ..# #| #|||||#|      #
#      .#|||||| ..  |# ## |#| ...#|#|||#|      #    #      .#|||||| ..  |# ## |#| ...#|#|||#|      #    #      .#|||||| ..  |# ## |#| ...#|#|||#|      #
#      .#|||#|# .# .#| #| ##|.#..#|||||#|      #    #      .#|||#|# .# .#| #| ##|.#..#|||||#|      #    #      .#|||#|# .# .#| #| ##|.#..#|||||#|      #
#      .#||||||############|######|||||#|      #    #      .#||||||############|######|||||#|      #    #      .#||||||############|######|||||#|      #
#   |...||#||||||#||||#|#||||||#|||||#||| |.|  #    #   |...||#||||||#||||#|#||||||#|||||#||| |.|  #    #   |...||#||||||#||||#|#||||||#|||||#||| |.|  #
#. .. ||||# .|||##|.  |#| .|| || .|||#. #|  # .#    #. .. ||||# .|||##|.  |#| .|| || .|||#. #|  # .#    #. .. ||||# .|||##|.  |#| .|| || .|||#. #|  # .#
|| |  ...||  ...##| |  #| .|. |. #####  .. .| ||    || |  ...||  ...##| |  #| .|. |. #####  .. .| ||    || |  ...||  ...##| |  #| .|. |. #####  .. .| ||
|| ||||| || ||||#|  .  |. |. |#. ||||| |#| || ||    || ||||| || ||||#|  .  |. |. |#. ||||| |#| || ||    || ||||| || ||||#|  .  |. |. |#. ||||| |#| || ||
.# |.....#|....|#.||||.|||##.|#|....||.#||.#. #.    .# |.....#|....|#.||||.|||##.|#|....||.#||.#. #.    .# |.....#|....|#.||||.|||##.|#|....||.#||.#. #.
 #.|||||||#############################| ||| .#      #.|||||||#############################| ||| .#      #.|||||||#############################| ||| .#
 ||       ##||#||#||||||#||#||#||#||##.      ||      ||       ##||#||#||||||#||#||#||#||##.      ||      ||       ##||#||#||||||#||#||#||#||##.      ||
  #       .#|||||||||#||#|||||||||||#|       #        #       .#|||||||||#||#|||||||||||#|       #        #       .#|||||||||#||#|||||||||||#|       #
  ||       |#||||||||||||||||||||||#|       ||        ||       |#||||||||||||||||||||||#|       ||        ||       |#||||||||||||||||||||||#|       ||
  .#        |#||||||||||||||||||||#|        #.        .#        |#||||||||||||||||||||#|        #.        .#        |#||||||||||||||||||||#|        #.
   ||        |#||||||||||||||||||#|        ||          ||        |#||||||||||||||||||#|        ||          ||        |#||||||||||||||||||#|        ||
    #.        .######|#|#########|        .#            #.        .######|#|#########|        .#            #.        .######|#|#########|        .#
    .#.         |#####||||#####|         .#.            .#.         |#####||||#####|         .#.            .#.         |#####||||#####|         .#.
     |#           ||########||           #.              |#           ||########||           #.              |#           ||########||           #.
      |#             ......             #|                |#             ......             #|                |#             ......             #|
       |#.                            .#|                  |#.                            .#|                  |#.                            .#|
        |#.                          .#.                    |#.                          .#.                    |#.                          .#.
         .#|                        |#.                      .#|                        |#.                      .#|                        |#.
           |#|                    |#|                          |#|                    |#|                          |#|                    |#|
            .|#|.              .|#|.                            .|#|.              .|#|.                            .|#|.              .|#|.
               |##||.      .||##|                                  |##||.      .||##|                                  |##||.      .||##|
                 .||########||.                                      .||########||.                                      .||########||.

Scale With Search  2026  [scalewithsearch.com](https://scalewithsearch.com)
```
