Intersection Observer
Intersection Observer reports when elements cross visibility thresholds relative to a root viewport, replacing scroll-event geometry polling with an asynchronous, frame-aligned callback.
Definition
Intersection Observer is a browser API that watches elements and delivers asynchronous callbacks when their intersection ratio with a root (default the viewport) crosses configured thresholds. It replaces manual scroll handlers with getBoundingClientRect, avoiding layout reads per scroll event and batching observations per frame.
Context and scope
Used for lazy loading images and components, infinite scroll triggers, sticky-header state, visibility analytics, and pausing video or animation off-screen.
Common misconceptions
- It fires on every scroll event — callbacks are frame-batched and threshold-crossing driven, not scroll driven
- It measures the whole element — rootMargin and threshold define the intersection geometry precisely
- It watches only the viewport — any scrollable ancestor or arbitrary element can serve as the root
Anti-patterns
- Attaching hundreds of observers instead of one observer watching hundreds of elements
- Computing element geometry in scroll handlers to decide visibility and thrashing layout on mobile
- Unobserving immediately then re-observing on state change and paying setup churn per toggle
Related concepts
Related examples
Authoritative source
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
What it is
The old pattern — scroll listener, then getBoundingClientRect for each candidate — forces layout work proportional to event frequency times element count. Intersection Observer inverts it: register elements once, and the engine computes intersections after layout and paint, invoking your callback with only what changed.
How it works
An observer holds a root, rootMargin that grows or shrinks the root box, and a threshold list from 0 to 1. Entries report current ratio, bounding rectangles, and isIntersecting. Callbacks run after rendering, so measurements are stable and reads never force layout. One observer can watch many targets efficiently.
When to use it
Lazy loading below-the-fold content, firing analytics when sections become visible, loading more list pages before the footer arrives, pausing expensive work when hidden. Combine with content-visibility for rendering skips and with native lazy loading for plain images.
Pitfalls
Entries are snapshots: rapid scrolling can coalesce crossings, so counters that must count every passage need threshold tuning or in-view dwell logic. isIntersecting at threshold 0 fires on zero-area intersections in some edge geometries; test with sticky or transformed parents.