No Login Data Private Local Save

Lazy Loading Demo - Online See Intersection Observer

12
0
0
0
0 (eager)1 (strict)
Pending: 18
Loaded: 0
In View: 0
Observer Active

Intersection Observer Lazy Loading Demo

Scroll down to see cards load as they enter the viewport

Scroll down to trigger lazy loading
All cards loaded!

Scroll back up and click Reset All to try again with different settings.

Frequently Asked Questions

The Intersection Observer API is a browser API that allows you to asynchronously observe changes in the intersection of a target element with an ancestor element or the viewport. It provides a performant way to detect when elements enter or leave the visible area, making it ideal for lazy loading, infinite scrolling, and visibility-based analytics without expensive scroll event listeners.

Lazy loading with Intersection Observer works by placing placeholder content (like skeleton screens or low-res images) on the page and using the observer to detect when those placeholders approach or enter the viewport. Once detected, the real content—such as high-resolution images, iframes, or dynamically loaded data—is fetched and rendered. This reduces initial page load time and saves bandwidth by only loading content that users actually scroll to see.

The threshold option defines what percentage of a target element must be visible before the observer's callback is triggered. It accepts a single number (0–1) or an array of numbers. A threshold of 0 means the callback fires as soon as even one pixel of the target is visible. A threshold of 0.5 requires 50% visibility, and 1 requires the entire element to be visible. You can use multiple thresholds like [0, 0.25, 0.5, 0.75, 1] to get fine-grained visibility updates.

rootMargin expands or shrinks the root element's bounding box before calculating intersections. It uses CSS margin syntax (e.g., "100px", "50px 20px", "-50px"). A positive value (like "200px") causes the observer to fire 200px before the element actually enters the viewport—great for eager preloading. A negative value (like "-80px") delays triggering until the element is 80px inside the viewport, making loading more conservative. This gives developers precise control over when lazy loading triggers.

Scroll events fire synchronously at high frequency (potentially 60+ times per second), and calculating element positions on every scroll tick using getBoundingClientRect() forces expensive layout recalculations. Intersection Observer runs asynchronously and is optimized by the browser to batch observations, reducing main thread work. This results in significantly better performance—especially on mobile devices—and avoids janky scrolling experiences.

Yes, it is best practice to call observer.unobserve(target) once the content has been loaded and no further observation is needed. This frees up resources and reduces the number of elements the browser needs to check on every intersection calculation. For single-fire lazy loading (like loading an image once), always unobserve after loading. For continuous tracking (like visibility analytics), you may want to keep observing.

Native lazy loading uses the loading="lazy" attribute on <img> and <iframe> elements. It's supported in all modern browsers and requires zero JavaScript. However, it offers no control over when loading triggers (threshold, rootMargin), cannot be applied to dynamically injected content or non-image elements, and doesn't support loading placeholders with custom transitions. Intersection Observer gives you complete control over the lazy loading behavior for any type of content.

Beyond lazy loading images, Intersection Observer powers: infinite scrolling (detecting a sentinel element to load more content), sticky headers that change appearance when they leave the viewport, scroll-triggered animations, ad visibility tracking for impression counting, video auto-play/pause based on viewport presence, and performance monitoring to track which parts of a page users actually see. It's one of the most versatile modern browser APIs.

Intersection Observer is supported in all modern browsers including Chrome (51+), Firefox (55+), Safari (12.1+), and Edge (15+). It covers approximately 97%+ of global web traffic. For legacy browsers like Internet Explorer, a polyfill is available. The API is widely considered safe for production use without fallbacks, though for critical lazy loading you can combine it with a scroll-event fallback for maximum compatibility.

This demo creates an Intersection Observer with your chosen threshold and rootMargin values. Each card starts as a skeleton placeholder. As you scroll, the observer detects when a card's placeholder intersects with the viewport (adjusted by rootMargin) and meets the visibility threshold. A brief loading animation plays, then the card reveals its content. Stats update in real time showing how many cards have been loaded, how many are pending, and how many are currently in view. You can reset and experiment with different settings to see how they affect loading behavior.