IntersectionObserver internals

Slap yourself if

You think IntersectionObserver fires on scroll events or assume it is just a throttled getBoundingClientRect.

Why this exists

Because IntersectionObserver is routinely used as a performance fix while teams misunderstand its scheduling, miss edge cases, and ship logic that breaks under compositing, transforms, or async layout.

Mental model

IntersectionObserver is a rendering-pipeline hook, not an event listener. Observations are delivered asynchronously based on layout and compositing state, not user input.

  • The browser tracks observed targets against a root using geometry from layout.
  • Intersections are evaluated during rendering updates, not on scroll events.
  • Entries are queued and delivered asynchronously after layout and paint decisions.
  • Multiple visibility changes can collapse into a single callback.
  • Assuming one callback per scroll tick.
  • Relying on synchronous geometry inside the callback.
  • Using IntersectionObserver as a precise visibility detector.
  • Missing intersections due to transforms or clipping contexts.

IntersectionObserver schedules visibility checks as part of the rendering pipeline and delivers batched, asynchronous intersection entries based on layout state.

  • Says it listens to scroll.
  • Expects synchronous accuracy.
  • Cannot explain batching.
  • Treats it as a geometry API.

Deep dive

Requires Pro

Premium deep dives include more internals, more scars.

Where IntersectionObserver lives in the rendering pipeline

Why entries arrive late, merged, or skipped

How transforms and clipping break assumptions

Why IntersectionObserver is intentionally imprecise

How IntersectionObserver answers give people away