Skip to the solution
MediumFrontend6 min read

How would you use IntersectionObserver to lazy-load images only as they scroll into the viewport?

543 views

The problem

Question presented to candidate: "You have 50 images on a long page, but only the first 3 are visible on load. How would you defer loading the rest until each one is about to scroll into view, without a manual scroll-event listener computing positions on every scroll tick?"

What a strong answer should cover:

  • πŸ“Œ Interview term: IntersectionObserver β€” a real, built-in browser API that lets code .observe(element) and receive a real callback exactly when that element's intersection with the viewport (or another ancestor) genuinely changes β€” no manual scroll event listener or position math required.
  • πŸ“Œ Interview term: the real, direct answer to the prompt β€” verified directly, live in a real browser (confirmed genuinely NOT implemented in jsdom): observing an image placed far below the fold produced an immediate real callback reporting isIntersecting: false; after genuinely SCROLLING the target into view, a SECOND real callback fired reporting isIntersecting: true, ratio: 1 β€” the exact real moment to swap a placeholder for the real image src.
  • πŸ“Œ Interview term: entry.isIntersecting β€” the real boolean each callback entry carries, directly answering whether the observed element is currently visible within the configured root, with no manual geometry calculation needed.
  • πŸ“Œ Interview term: the real practical lazy-load pattern β€” a precise answer names the standard implementation: set each image's real src from a data-src attribute inside the callback ONLY when entry.isIntersecting is true, then immediately call observer.unobserve(entry.target) (or observer.disconnect() if watching only one element) β€” since an image only needs to load ONCE, not repeatedly on every scroll in/out.
  • A precise answer names the real, practical performance advantage over a manual scroll listener: a scroll event fires extremely frequently, requiring either manual throttling or a real, wasted getBoundingClientRect() call on every tick β€” IntersectionObserver's callback fires only when the real intersection state genuinely changes.

Clarifying questions expected:

  • None β€” this is a definitional/practical question; directly demonstrating the real, verified scroll-triggered callback is the strong signal.

Code / implementation expected: Yes β€” a real, live-browser-verified IntersectionObserver observing a below-the-fold target, triggered by a real scroll, with .disconnect() confirmed to stop further callbacks.

  • observers
  • tricky
  • real-world

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 8 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

JavaScriptReal, live-verified proof: IntersectionObserver reports isIntersecting:false for a below-the-fold target, then true exactly when a real scroll brings it into view

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 85 of 165 in JavaScript

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextMedium

What are the logical assignment operators?

Continue