๐Ÿ‘๏ธ JavaScript

Intersection Observer โ€” Lazy Loading & Scroll Animations Done Right

๐Ÿ“… Jul 4, 2026 โฑ 3 min read

Scroll listeners fire hundreds of times per second and jank the page. IntersectionObserver watches visibility for free, off the main thread.

Reveal-on-scroll (the portfolio effect)

const io = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add("visible");
      io.unobserve(entry.target);      // animate once, stop watching
    }
  });
}, { threshold: 0.15 });               // fire at 15% visible

document.querySelectorAll(".reveal").forEach((el) => io.observe(el));
.reveal { opacity: 0; translate: 0 24px; transition: 0.5s ease; }
.reveal.visible { opacity: 1; translate: 0 0; }

Infinite scroll

const sentinel = document.querySelector("#load-more-sentinel");
new IntersectionObserver(async ([entry]) => {
  if (entry.isIntersecting) await loadNextPage();
}, { rootMargin: "400px" }).observe(sentinel);   // start loading 400px early

The options

Respect prefers-reduced-motion on the animations, always.

โ† All Articles