Observer APIs: Intersection, Mutation & Resize

Stop using terrible scroll and resize event hacks. Discover the modern, highly-optimized Observer APIs that let you respond to layout and DOM changes efficiently.

JavaScript7 min readConcept 38 of 62

The Performance Saviors

In the past, if you wanted to know when an element scrolled onto the screen, you had to attach an event listener to the window.onscroll event.

Because the user scrolls hundreds of pixels a second, your function would fire hundreds of times a second, bringing the browser to a crawl. The modern **Observer APIs** were created to solve this.

The Big Three

1. IntersectionObserver: Tells you exactly when an element enters or leaves the screen (or another container). Used for lazy-loading images and infinite scrolling.

2. ResizeObserver: Tells you when a specific element changes its width or height. It is a massive improvement over listening to window.onresize.

3. MutationObserver: Tells you when the DOM tree itself changes, such as a node being added/removed or a class name changing.

The Standard Pattern

All observers follow the exact same architectural pattern:

First, you instantiate the observer with a callback function: const observer = new IntersectionObserver((entries) => { ... }).

Second, you tell it what element to watch: observer.observe(myDiv).

When the criteria is met, the browser fires your callback asynchronously, passing an array of entries containing the new data.

The Intersection Simulator

Scroll the container below. Watch how the observer only fires its callback at the exact moment the target element crosses the threshold, saving immense amounts of CPU power compared to a scroll listener.

The Intersection Simulator

Scroll to Trigger
// 1. Create the Observer
const observer = new IntersectionObserver((entries) => {
// The callback ONLY fires when a threshold is crossed!
entries.forEach(entry => {
console.log("isIntersecting:", entry.isIntersecting);
});
});
// 2. Start watching an element
observer.observe(targetElement);
// 3. Stop watching (prevents memory leaks)
observer.disconnect();
Viewport (The Root)
Scroll Down ↓
Target Element
HIDDEN
Scroll Up ↑
Console OutputOnly fires on threshold
Scroll target into view...
iUnlike a traditional scroll event which fires hundreds of times per second and crushes the CPU, this callback only fired twice: once when it entered the screen, and once when it left!

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1Why is `IntersectionObserver` better than a `window.addEventListener('scroll')` hack?
  2. 2If you want to run a function every time a specific `<div>` is made wider by CSS Grid or Flexbox, what should you use?
  3. 3What critical step must you take when an observed element is removed from the screen?

Remember this

  • Stop using scroll and resize event listeners for layout calculations.
  • IntersectionObserver fires when elements enter or leave a container.
  • ResizeObserver fires when an element's physical dimensions change.
  • MutationObserver fires when DOM nodes or attributes are modified.
  • Always call observer.disconnect() to prevent memory leaks when elements are destroyed.

Done with this concept?

Mark it complete to track your progress. No login needed.