Web Performance & SEO Guide
Lazy Loading Explained: What It Is, How It Works, and When Not to Use It
The complete practical guide to lazy loading for images, iframes, and videos, including the critical mistake that caused one site to lose 20% of its organic traffic overnight.
3 Key Facts About Lazy Loading You Should Know
- Lazy loading can reduce initial page weight by 50 to 80% on image-heavy pages, directly improving load time, Time to Interactive, and Core Web Vitals scores for users who may never scroll far enough to see every image.
- Applying lazy loading to the hero image is one of the most damaging technical SEO mistakes a developer can make. A documented 2025 case study shows a site that lazy-loaded all images saw its LCP deteriorate from 1.8 seconds to 4.2 seconds, triggering a 20% drop in organic traffic despite a PageSpeed score jumping from 65 to 92.
- As of 2024, 16% of mobile websites still lazy-load their LCP element, according to the HTTP Archive Web Almanac. That means roughly 1 in 6 sites is actively hurting its own search rankings with a single misapplied HTML attribute.
| Resource Type | Use Lazy Loading? | How to Implement | Key Caveat |
|---|---|---|---|
| Hero / above-the-fold images | Never | Add fetchpriority="high" |
Lazy loading the LCP element tanks your ranking |
| Below-the-fold images | Yes, always | loading="lazy" on <img> |
Must include width and height to avoid CLS |
| YouTube / video iframes | Yes | loading="lazy" on <iframe> |
Saves ~500KB per YouTube embed on initial load |
| Google Maps iframes | Yes | loading="lazy" on <iframe> |
Maps fire dozens of sub-requests; always defer |
| Social media embeds | Yes | loading="lazy" or Intersection Observer |
Instagram saves 100KB+ gzipped on initial load |
| JavaScript components | Selective | Intersection Observer API or dynamic import() |
Use for heavy UI components loaded below the fold |
SEO Keyword Research: Lazy Loading Search Terms
These are the search terms with the best combination of volume and ranking opportunity for this topic, based on real search intent signals. Low-to-medium competition terms are the priority because they let a well-structured article compete without requiring years of domain authority.
| Keyword / Search Term | Est. Volume | Competition | Intent |
|---|---|---|---|
| what is lazy loading | High | Medium | Informational |
| lazy loading images | High | Medium | Informational |
| lazy loading SEO | Medium | Low | Informational |
| how lazy loading works | Medium | Low | Informational |
| lazy loading vs eager loading | Medium | Low | Informational |
| does lazy loading hurt LCP | Medium | Low | Informational |
| native lazy loading HTML attribute | Medium | Low | Informational |
| lazy loading iframes | Medium | Low | Informational |
| Intersection Observer API lazy loading | Medium | Low | Informational |
| lazy loading Core Web Vitals | Medium | Low | Informational |
| lazy load hero image mistake | Medium | Low | Informational |
What Is Lazy Loading?
Lazy loading is a web performance technique that defers the loading of non-critical resources until the user actually needs them, typically when those resources enter or approach the browser's visible area (the viewport) as the user scrolls. Instead of loading every image, video, and iframe on a page the moment it first opens, lazy loading prioritizes the content the user sees immediately and loads everything else progressively as they scroll down.
The name comes from the programming concept of "lazy evaluation," where computation is delayed until the result is needed rather than performed upfront. Applied to web pages, the logic is the same: why force a browser to download a product image that sits 3,000 pixels below the fold when the user might never scroll that far?
For image-heavy pages, lazy loading can reduce initial page weight by 50 to 80%, which translates directly into faster load times, lower bandwidth usage, and better scores on Google's Core Web Vitals. Every image that does not load on the first paint is an image that is not slowing down your LCP, not blocking the main thread, and not consuming data that the user may never need.
How Lazy Loading Works
When a browser loads a webpage, it normally fetches every resource referenced in the HTML immediately: images, scripts, stylesheets, and iframes, whether they are visible on screen or buried at the bottom of a long page. This is called eager loading and it is the default browser behavior.
Lazy loading intercepts this behavior and tells the browser to skip certain resources on the initial load. The browser instead tracks the user's scroll position. When a lazy-loaded element gets close enough to entering the viewport (within a certain distance threshold), the browser fetches it then. From the user's perspective, images appear to load just before they become visible, so the experience feels seamless on normal connections while the page itself loads much faster.
The Three Ways to Implement Lazy Loading
There are three distinct implementation methods, each suited to different situations. Understanding the difference is important because choosing the wrong one can create performance problems instead of solving them.
1. Native lazy loading with the HTML loading attribute is the simplest method and the recommended approach for the vast majority of use cases. Add loading="lazy" to any <img> or <iframe> element. The browser handles all the viewport detection and loading timing automatically. No JavaScript required, no external libraries, no maintenance overhead. This attribute is supported in all major browsers as of 2020 and covers over 95% of global web traffic.
<!-- Lazy loading an image below the fold -->
<img
src="product-photo.webp"
loading="lazy"
width="800"
height="600"
alt="Blue leather office chair"
>
<!-- Lazy loading a YouTube embed -->
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
loading="lazy"
width="560"
height="315"
title="Product demo video"
></iframe>
2. The Intersection Observer API is a JavaScript-based approach that gives developers more granular control over when and how resources load. Instead of relying on the browser's built-in threshold, you define exactly when an element should trigger loading based on how far it is from the viewport, what percentage of it is visible, or any other custom condition. This is the right tool when you need to lazy-load components that native HTML attributes cannot handle: JavaScript modules, dynamically generated content, CSS background images, or complex third-party widgets.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
3. JavaScript lazy loading libraries like vanilla-lazyload (2.4KB) wrap the Intersection Observer API in a ready-made solution with additional features like responsive image support, CSS background image handling, and connection-speed awareness. These are appropriate when you need a battle-tested solution across a complex site without writing and maintaining your own Observer implementation.
loading="lazy". It handles 90% of real-world use cases with zero JavaScript and zero dependencies. Only reach for the Intersection Observer API when you need to lazy-load something that the native attribute cannot target.
The Lazy Loading Mistake That Tanks Rankings
This is the most important section of this entire guide. Never apply lazy loading to your hero image or any image that appears above the fold. This is not a minor caveat. It is the difference between a fast page and a broken one.
Here is what happens when you lazy-load your hero image: the browser sees the loading="lazy" attribute and decides to deprioritize that resource. It starts loading scripts, stylesheets, fonts, and other assets instead. By the time those finish and the browser circles back to load the hero image, a significant amount of time has passed. The user is staring at an empty space where the most important visual on the page should be. Your Largest Contentful Paint (LCP) time skyrockets.
In August 2025, Google's developer advocate Martin Splitt discussed this exact problem on the Search Off the Record podcast. He disclosed that Google's own team found this mistake on developers.google.com, where their CMS was defaulting all images to loading="lazy", including the main hero image. If Google's own engineers shipped this bug to production, it is not surprising that it is widespread.
The real-world consequences are not theoretical. A documented 2025 case study from SEO agency Apollo Digital showed a client site where applying lazy loading to all images caused LCP to deteriorate from 1.8 seconds to 4.2 seconds, even as the Lighthouse/PageSpeed score jumped from 65 to 92. Organic traffic dropped 20%. The lab score improved because the total byte weight of the page looked lower. But the field data told the truth: the most critical element was loading far too slowly for real users, and Google's ranking signals responded accordingly.
loading="lazy". Remove it immediately. Add fetchpriority="high" instead to tell the browser to load that image as its top priority.
Lazy Loading: What to Do and What to Avoid
Do This
- Apply
loading="lazy"to all below-the-fold images - Add
fetchpriority="high"to your hero image - Always include
widthandheighton lazy-loaded elements - Lazy-load YouTube, Maps, and social media iframes
- Use native lazy loading before reaching for JavaScript
- Test with PageSpeed Insights field data after implementing
- Verify in rendered HTML that the LCP image has a real
src, notdata-src
Never Do This
- Apply
loading="lazy"to the hero or banner image - Lazy-load any image visible on initial viewport without scrolling
- Omit
widthandheighton lazy-loaded images (causes CLS) - Use
data-srcfor the LCP element (crawler cannot see it) - Trust only the Lighthouse score to validate lazy loading
- Apply lazy loading globally to all images without auditing
- Use heavy lazy loading scripts that block the main thread
Lazy Loading Iframes: The Biggest Quick Win Most Sites Miss
Most developers know about lazy loading images. Far fewer realize that the same native loading="lazy" attribute works on iframes, and the performance savings from lazy-loading iframes are often even larger than for images.
A single YouTube embed fires dozens of network requests and loads several hundred kilobytes of third-party JavaScript the moment the page opens, whether the user ever watches the video or not. Lazy-loading that YouTube iframe saves approximately 500KB on the initial page load. An Instagram embed saves over 100KB gzipped. A Spotify embed saves 514KB. A Google Maps iframe fires so many sub-requests that it can single-handedly push a page's Time to Interactive past the three-second mark on mobile.
The implementation is identical to lazy-loading an image. Add loading="lazy" to the <iframe> tag and always include explicit width and height attributes. Without declared dimensions, the browser cannot reserve space for the iframe, which causes a layout shift (CLS hit) when it eventually loads.
<!-- Before: loads 500KB of YouTube JS immediately -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
width="560" height="315"></iframe>
<!-- After: defers until user scrolls near it -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
loading="lazy"
width="560"
height="315"
title="Product demo video"></iframe>
Performance-First Landing Page Development
Your Landing Page Should Load in Under 2 Seconds. Ours Do.
We build landing pages where lazy loading is applied correctly: hero images load first, below-the-fold content defers, and no YouTube embed is ever blocking your initial page paint.
See Our Landing Page ServiceAffordable pricing | Fast delivery | Performance-optimized code
Lazy Loading and SEO: What Google Actually Says
There is a persistent misconception that lazy loading hides content from Google because Googlebot might not scroll the page. This is outdated thinking. Google's crawler has supported JavaScript rendering for years and does scroll pages to trigger lazy-loaded content during indexing. When implemented with native loading="lazy", there is no indexing risk at all because the image src attribute is present in the HTML from the start and Googlebot can discover it without scrolling.
The real SEO risk from lazy loading is not indexation. It is LCP. Lazy loading the wrong images can destroy your Core Web Vitals scores, and poor Core Web Vitals translate to lower search rankings through Google's Page Experience signal. The relationship is direct: slow LCP means worse rankings means less traffic.
Google's Martin Splitt has confirmed this distinction clearly. Correctly implemented lazy loading, applied only to below-the-fold content, is not just safe for SEO but actively beneficial. It improves the metrics Google measures. Incorrectly implemented lazy loading that touches the LCP element creates real ranking penalties through degraded performance scores.
One additional nuance worth knowing: if you use a JavaScript-based lazy loading approach where the image URL is stored in a data-src attribute instead of the standard src attribute, Googlebot may not discover the image at all unless JavaScript execution succeeds and the attribute swap happens correctly. Always verify the rendered HTML in Google Search Console's URL Inspection tool to confirm that your LCP image appears with a real src value, not a placeholder.
Why Lazy Loading Matters More on Landing Pages Than Anywhere Else
For businesses running paid search campaigns, every visitor to a landing page has a cost attached to them. That cost is paid whether the visitor converts or bounces in three seconds because the page was still loading. Lazy loading is one of the highest-leverage performance fixes for landing pages because landing pages tend to be image-heavy, they often embed video demos or testimonial videos, and they are frequently the first page a visitor sees from an ad click.
A correctly implemented landing page should have its hero image loaded eagerly with fetchpriority="high", its above-the-fold product screenshots and trust badges loaded normally, and every image or embed below the first fold lazy-loaded with native browser attributes. This pattern guarantees the fastest possible perceived load for the most critical moment: the first two seconds after the ad click, when the visitor is deciding whether to stay or leave.
There is also a direct paid search impact. Google Ads Quality Score includes a landing page experience component. A landing page that loads fast and performs well on Core Web Vitals gets a higher Quality Score, which means lower cost per click and better ad placement. Getting lazy loading right on a landing page is not just an SEO optimization. It pays dividends on every ad dollar you spend.
Lazy Loading Implementation Checklist
| # | Action | Why |
|---|---|---|
| 1 | Audit every page: identify which image is the LCP element | This image must never be lazy-loaded |
| 2 | Add fetchpriority="high" to the LCP / hero image |
Tells the browser to prioritize this above everything else |
| 3 | Add loading="lazy" to every image below the first fold |
Reduces initial page weight and speeds up LCP indirectly |
| 4 | Confirm all lazy-loaded <img> tags have width and height set |
Prevents CLS (layout shift) when images load on scroll |
| 5 | Add loading="lazy" to all YouTube, Maps, and social iframes |
Saves hundreds of KB in third-party scripts on initial load |
| 6 | Verify implementation with Google Search Console URL Inspection | Confirms the rendered HTML shows real src values, not data-src |
| 7 | Check PageSpeed Insights field data (not just the lab score) | Lab scores can improve while field LCP gets worse; always check both |
| 8 | Wait 28 days and monitor Google Search Console Core Web Vitals report | CrUX data takes a full cycle to reflect real-user improvements |
Stop Paying for Traffic That Bounces Immediately
Get a Landing Page Where Performance Is Built In, Not Bolted On
Every landing page we build has correct lazy loading from day one. No hero image mistakes, no iframe bloat, no LCP surprises. Just a fast, clean page that converts.
Get Your High-Performance Landing PageNo long-term contracts | Transparent pricing | Results-focused
Frequently Asked Questions
What is lazy loading and how does it work?
Lazy loading is a performance technique that defers the loading of off-screen images, iframes, and videos until the user scrolls close to them, rather than loading everything when the page first opens. It works by monitoring the user's scroll position through the browser's built-in logic (with the native loading="lazy" HTML attribute) or through JavaScript's Intersection Observer API. When a lazy-loaded element approaches the visible area of the screen, the browser fetches it. This reduces the initial page weight, improves Time to Interactive, and lowers the amount of data downloaded by users who do not scroll the full page.
Does lazy loading hurt SEO or LCP?
Applied correctly, lazy loading improves SEO by reducing page weight and improving Core Web Vitals scores. Applied incorrectly, it can severely damage rankings. The specific mistake that hurts SEO is lazy-loading the hero image or any above-the-fold image, which delays the Largest Contentful Paint (LCP) metric. A 2025 case study documented a site that lost 20% of organic traffic after lazy-loading all images, because the hero image LCP deteriorated from 1.8 seconds to 4.2 seconds. The PageSpeed score actually went up to 92 while the real-user ranking signal collapsed. The fix is simple: never add loading="lazy" to images visible in the initial viewport.
How do I implement native lazy loading in HTML?
Native lazy loading requires a single HTML attribute: add loading="lazy" to any <img> or <iframe> element that appears below the fold. Always pair it with explicit width and height attributes to prevent layout shift. For your hero or banner image, use fetchpriority="high" instead to tell the browser to prioritize it. Native lazy loading is supported in all major browsers since 2020 and covers over 95% of global web traffic, making it the recommended approach before reaching for any JavaScript library.
Should I lazy load iframes like YouTube or Google Maps?
Yes, and this is one of the most impactful performance improvements most sites are not making. A YouTube iframe loads approximately 500KB of third-party JavaScript on page open even if no one ever watches the video. Adding loading="lazy" to the iframe tag defers all of that until the user scrolls near it. Google Maps, Instagram embeds, and Spotify players all have similarly large initial footprints. The only caveat is that you must include explicit width and height on all lazy-loaded iframes, otherwise the browser cannot reserve space for them and your CLS score will be affected when they eventually load.
What is the difference between lazy loading and eager loading?
Eager loading (the browser default) loads every resource immediately when the page is first requested, regardless of whether the user can currently see those resources. Lazy loading defers non-critical resources until they are needed. Eager loading makes sense for above-the-fold content like the hero image, where loading as fast as possible is the goal. Lazy loading makes sense for everything below the fold, where deferring the load reduces initial page weight without affecting what the user sees first. In practice, a well-optimized page uses both: fetchpriority="high" on the hero image for maximum eager loading priority, and loading="lazy" on everything else below the fold.
Does Google's crawler handle lazy-loaded images correctly?
Yes, when implemented with native loading="lazy" on the <img> tag, Googlebot can discover and index lazy-loaded images because the src attribute is present in the HTML from the start. The indexation risk arises with JavaScript-based lazy loading approaches that use a data-src attribute to store the real image URL, swapping it into src only when the user scrolls. If JavaScript execution fails or the crawler does not trigger the swap, those images remain invisible to Google. Always use native lazy loading where possible, and verify your implementation with Google Search Console's URL Inspection tool to confirm that image URLs appear correctly in the rendered HTML.
How do I know which image is my LCP element?
The easiest way is to run your page through Google PageSpeed Insights and look at the "Largest Contentful Paint element" diagnostic in the lab data section. It will highlight the exact element responsible for your LCP score. You can also open Chrome DevTools, go to the Performance panel, record a page load, and hover over the "LCP" marker in the timeline. In almost every case, the LCP element is the hero image, banner image, or a large above-the-fold heading. Once you identify it, confirm that it does not have loading="lazy" in its HTML, and add fetchpriority="high" to ensure the browser treats it as its top loading priority.
Does lazy loading affect landing page performance and conversion rates?
Lazy loading has a direct impact on landing page performance and conversion rates, but the direction depends entirely on implementation. Correct lazy loading makes landing pages load faster, reduces bounce rate, and improves Google Ads Quality Score, which lowers your cost per click. According to Portent data, conversion rates drop from 40% at one second to 29% at three seconds, meaning every fraction of a second saved on initial load has a measurable revenue impact. Incorrect lazy loading that delays the hero image can do the opposite: inflate your Lighthouse score while making the page feel slower to real users, hurting both conversions and organic rankings simultaneously.