Community JavaScript Snippet

IntersectionObserver Batched With rootMargin

On a feed with 200 cards, creating one IntersectionObserver per card pushed our scroll frame to 14ms. This is the single shared observer with `rootMargin` prefetch and a batched callback that brought it back to 4ms.

IntersectionObserver Batched With rootMargin

On a feed with 200 cards, creating one IntersectionObserver per card pushed our scroll frame to 14ms. This is the single shared observer with `rootMargin` prefetch and a batched callback that brought it back to 4ms.

JavaScript
Frontend
3 snippets
intersection-observer
js-dom
performance
frontend
emmakim

By @emmakim

April 9, 2026

·

Updated May 18, 2026

500 views

9

Rate

Sharing one observer is the optimization the spec already enables but most code does not use. The browser batches the callback for you (entries arrive as an array per tick), so handling them in groups instead of per-element keeps the scroll frame cheap. The Set of currently-visible elements is what makes the diff possible: without it, the callback fires once on initial observe with isIntersecting: false for every element, and naive code marks them all hidden. The onChange listener pattern means a feed component, an analytics module, and a lazy-image loader can all subscribe to the same observer.