Lazy Loading
Lazy loading defers offscreen assets to improve initial load, but misusing it can hurt LCP or delay content discovery.
Definition
Lazy loading defers loading of offscreen assets (images/iframes) such as loading="lazy". It reduces initial payload, but lazy-loading the main hero image can hurt LCP. If important content appears only after interaction/scroll, indexing can become less reliable.
Why it matters
- Reduces initial payload and improves initial page load speed
- Saves bandwidth — especially friendly for mobile users
- Helps avoid CLS when paired with reserved dimensions
- Native browser support via loading="lazy" — no extra JS needed
- Especially effective for long pages with many images
- Misuse can hurt LCP and indexability (don't lazy-load hero images)
- Lazy iframes (like YouTube embeds) significantly reduce initial blocking
How to implement
- Don't lazy-load hero images — use fetchpriority="high" or <link rel="preload">
- Apply loading="lazy" consistently to below-the-fold images
- Ensure important content isn't hidden behind scroll/interaction (affects crawlers)
- Always set width and height on lazy images to avoid CLS
- Iframes (YouTube embeds) also support loading="lazy"
- Use Intersection Observer for advanced control (animations, etc.)
- Test: verify in DevTools Network panel that images load only when needed
Examples
html
<!-- Below-fold images use lazy -->
<img src="/below-fold.webp" alt="Product image" loading="lazy" width="800" height="600" />
<!-- Hero image uses eager (default) + fetchpriority -->
<img src="/hero.webp" alt="Main visual" loading="eager" fetchpriority="high" />
<!-- Iframes can also be lazy -->
<iframe src="https://www.youtube.com/embed/xxx" loading="lazy"></iframe>html
// Fine-grained control over lazy loading
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, { rootMargin: '100px' });
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});Related
Tutorials
FAQ
Common questions about this term.