Skip to content

Intersection Observer for Lazy Loading

IntersectionObserver provides fine-grained control over when resources load by detecting when elements enter the viewport.

const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target;
loadResource(el);
observer.unobserve(el); // Stop observing once loaded
}
});
}, {
rootMargin: '200px', // Start loading 200px before visible
threshold: 0.1 // Trigger when 10% visible
});
function lazyLoad(element) {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
// Trigger loading
element.classList.add('visible');
element.src = element.dataset.src;
observer.disconnect();
}
}, { rootMargin: '100px' });
observer.observe(element);
}
// Usage
document.querySelectorAll('[data-lazy]').forEach(lazyLoad);
const sentinel = document.querySelector('#scroll-sentinel');
const observer = new IntersectionObserver(async ([entry]) => {
if (entry.isIntersecting) {
const items = await fetchMoreItems();
appendItems(items);
}
}, { rootMargin: '400px' });
observer.observe(sentinel);
  • Use rootMargin to start loading before the element is visible
  • Call unobserve() or disconnect() after loading to stop observing
  • Set appropriate threshold values — 0 is often best
  • Avoid observing hundreds of elements simultaneously
  • IntersectionObserver provides custom control over lazy loading
  • Use rootMargin to preload before visibility
  • Always unobserve/disconnect after loading
  • Great for infinite scroll, image loading, and ad loading