100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What Is the Intersection Observer API and Why Use It?

Learn what the Intersection Observer API does, how it beats scroll-event polling, and how to use it for lazy loading.

mediumQ127 of 224 in Web Development Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

The Intersection Observer API lets you asynchronously detect when a target element enters or exits the viewport (or another ancestor element), without the expensive layout-reading loops that manual scroll-event listeners require.

Traditionally, detecting visibility meant listening to scroll and resize events and repeatedly calling getBoundingClientRect(), which forces synchronous layout reads on the main thread and can cause jank, especially on scroll-heavy pages. Intersection Observer instead lets you register a callback with a target element, a root (defaulting to the viewport), and a threshold, and the browser notifies you asynchronously — off the critical rendering path — whenever the intersection ratio crosses that threshold. This makes it the standard tool for lazy-loading images, infinite scroll, scroll-triggered animations, and ad visibility tracking, all without hand-rolled scroll listeners. Because observation is push-based rather than poll-based, it is both more efficient and more accurate than manually computing intersection in a scroll handler.

  • Avoids expensive synchronous layout reads from getBoundingClientRect in scroll handlers
  • Runs asynchronously, off the main rendering critical path
  • Simplifies common patterns like lazy loading and infinite scroll
  • Supports configurable thresholds and a custom root, not just the viewport

AI Mentor Explanation

Intersection Observer is like a boundary umpire who only radios in when the ball actually crosses the boundary line, instead of a colleague who has to stare at the rope constantly and manually check its position every second. The constant-checking colleague wastes attention and reaction time even when nothing is happening near the rope. The boundary umpire’s push-based alert fires exactly when the crossing occurs, and never before. That event-driven, only-notify-on-crossing model is exactly what Intersection Observer gives you over manual scroll polling.

Step-by-Step Explanation

  1. Step 1

    Create the observer

    Instantiate new IntersectionObserver(callback, options) with a root, rootMargin, and threshold.

  2. Step 2

    Register targets

    Call observer.observe(element) for each element you want to track.

  3. Step 3

    Browser tracks intersection asynchronously

    The browser computes intersection ratios off the critical rendering path, not on every scroll event.

  4. Step 4

    Callback fires on threshold crossing

    When the observed element’s visibility crosses a configured threshold, the callback receives entries describing the change.

What Interviewer Expects

  • Understanding of why manual scroll + getBoundingClientRect polling is expensive
  • Ability to explain root, rootMargin, and threshold options
  • Practical use cases: lazy loading, infinite scroll, scroll animations, ad tracking
  • Awareness that observation is asynchronous and off the main rendering path

Common Mistakes

  • Manually polling scroll position instead of using the API
  • Forgetting to call unobserve() or disconnect() to avoid memory leaks
  • Not understanding that threshold can be an array for multiple trigger points
  • Assuming the callback fires synchronously on every pixel of scroll

Best Answer (HR Friendly)

The Intersection Observer API lets your code know automatically when an element scrolls into or out of view, without you having to write scroll listeners that constantly check positions yourself. It is commonly used for lazy-loading images or triggering animations as the user scrolls, and it is much more efficient than the old manual approach.

Code Example

Lazy-loading images with Intersection Observer
const observer = new IntersectionObserver((entries, obs) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target
      img.src = img.dataset.src
      obs.unobserve(img) // stop watching once loaded
    }
  })
}, {
  root: null, // viewport
  rootMargin: '200px', // start loading before it’s fully visible
  threshold: 0.01,
})

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img))

Follow-up Questions

  • How does rootMargin differ from threshold?
  • How would you implement infinite scroll using Intersection Observer?
  • What happens if you observe an element that is removed from the DOM?
  • How does Intersection Observer compare to the older scroll + getBoundingClientRect approach in terms of performance?

MCQ Practice

1. What is the main performance advantage of Intersection Observer over scroll-event polling?

Intersection Observer avoids the synchronous getBoundingClientRect calls typical of manual scroll handlers.

2. What does the threshold option control?

threshold defines the intersection ratio (0 to 1) that triggers the callback.

3. Which method stops observing a specific element?

unobserve() stops watching a single target; disconnect() stops watching all targets.

Flash Cards

What does Intersection Observer detect?When a target element enters or exits the viewport or a specified root element.

Why is it faster than scroll listeners?It runs asynchronously off the main thread instead of forcing synchronous layout reads.

What does rootMargin do?Expands or shrinks the root’s bounding box for intersection calculations.

Name a common use case.Lazy-loading images, infinite scroll, or scroll-triggered animations.

1 / 4

Continue Learning