Intersection Observer API
Also Known As
IntersectionObserver
lazy loading
scroll detection
TL;DR
A browser API that efficiently detects when elements enter or leave the viewport — replacing scroll event listeners for lazy loading, infinite scroll, and animation triggers.
Explanation
The Intersection Observer API calls a callback when a target element intersects with a root element (or the viewport). It is asynchronous and off the main thread — far more efficient than scroll event listeners which fire on every pixel of scroll. Use cases: lazy loading images, infinite scroll, triggering CSS animations when elements enter view, sticky header detection, and ad impression tracking. threshold (0.0-1.0) defines how much of the element must be visible to trigger, rootMargin pre-loads before the element is fully visible.
Common Misconception
✗ Scroll event listeners are fine for detecting element visibility — scroll events fire hundreds of times per second on the main thread; Intersection Observer is asynchronous and does not block rendering.
Why It Matters
Scroll event listeners for visibility detection cause main thread jank — Intersection Observer is the standard, performant replacement that does not affect scroll performance.
Common Mistakes
- Not disconnecting the observer after the element is loaded — the observer keeps running unnecessarily.
- threshold: 1.0 for lazy loading — waits until the element is fully visible; use 0.1 to preload before it appears.
- No rootMargin for lazy loading — images load exactly as they enter the viewport; add '200px' margin to preload ahead.
- Using Intersection Observer for precise scroll position — it only fires at intersection thresholds, not on every pixel.
Code Examples
✗ Vulnerable
// Scroll event — main thread, fires hundreds of times per second:
window.addEventListener('scroll', () => {
document.querySelectorAll('img[data-src]').forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < window.innerHeight) {
img.src = img.dataset.src; // Expensive DOM query on every scroll event
}
});
});
✓ Fixed
// Intersection Observer — async, efficient:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img); // Stop observing once loaded
}
});
}, { rootMargin: '200px', threshold: 0.1 }); // Preload 200px before visible
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
33
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Amazonbot 13
Perplexity 5
Google 4
Ahrefs 2
ChatGPT 2
Majestic 1
Also referenced
How they use it
crawler 25
crawler_json 1
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: Low
⚡ Quick Fix
Replace scroll event listeners with IntersectionObserver for lazy loading, infinite scroll, and animation triggers — it runs off the main thread with zero scroll performance impact
📦 Applies To
javascript ES2015
web
🔗 Prerequisites
🔍 Detection Hints
window.addEventListener('scroll') for lazy loading or visibility detection — should use IntersectionObserver
Auto-detectable:
✓ Yes
lighthouse
eslint
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Low
Context: File