Lazy Loading Impact on Web Vitals Metrics

Understand how lazy loading affects Core Web Vitals. Learn when lazy loading helps (below-fold images) and when it hurts (LCP images). Best practices for native and intersection-based lazy loading.

Optimization

Detailed Explanation

Lazy Loading and Web Vitals

Lazy loading delays resource loading until the resource is needed (typically when it enters or approaches the viewport). It is a powerful optimization technique, but applying it incorrectly can hurt Web Vitals.

Lazy Loading and LCP

Never lazy-load the LCP image. The LCP image is in the viewport on initial load, so lazy loading adds an unnecessary delay:

  1. Browser parses HTML
  2. Finds <img loading="lazy"> — does NOT start loading
  3. Renders the page layout
  4. Intersection Observer fires (image is in viewport)
  5. Now starts loading the image
  6. Image downloads and renders → LCP fires late

This can add hundreds of milliseconds to LCP.

<!-- BAD: LCP image with lazy loading -->
<img src="hero.webp" alt="Hero" loading="lazy">

<!-- GOOD: LCP image loads immediately -->
<img src="hero.webp" alt="Hero" fetchpriority="high">

<!-- GOOD: Below-fold image lazy loaded -->
<img src="gallery-3.webp" alt="Gallery" loading="lazy">

Lazy Loading and CLS

If lazy-loaded images do not have explicit dimensions, they cause layout shifts when they load and expand from 0x0 to their natural size:

<!-- BAD: CLS when image loads -->
<img src="photo.webp" alt="Photo" loading="lazy">

<!-- GOOD: Space reserved -->
<img src="photo.webp" alt="Photo" loading="lazy" width="400" height="300">

Browser-Native vs JavaScript Lazy Loading

Native loading="lazy":

  • No JavaScript overhead
  • Browser controls the loading threshold
  • Simpler implementation
  • Cannot customize the intersection threshold

Intersection Observer:

  • Customizable threshold (start loading when image is 200px from viewport)
  • Works for any resource (not just images)
  • Adds JavaScript overhead
  • More complex implementation

Best Practices

  1. Never lazy-load above-the-fold content (first viewport)
  2. Always include dimensions on lazy-loaded images
  3. Use native loading="lazy" for simplicity when possible
  4. Consider a loading threshold for JS-based solutions (start loading 200-300px before viewport)
  5. Lazy-load iframes for embedded content: <iframe loading="lazy">
  6. Use fetchpriority="low" on below-fold images to further deprioritize them

Use Case

Lazy loading strategy affects every image-heavy website. E-commerce product listing pages with hundreds of product images, social media feeds, image galleries, and blog archives all benefit from lazy loading below-fold images. The key is distinguishing between the LCP image (never lazy-load) and everything else (lazy-load aggressively).

Try It — Web Vitals Reference

Open full tool