Question presented to candidate: "Our product feed shows dozens of large photos and the page is slow on phones. Build an image component that only downloads its photo when it is about to scroll into view. It should show a placeholder first, fade the photo in when it arrives, and show a fallback with a retry button if the file fails."
Requirements:
- A reusable image component taking
src,alt,width,heightand a placeholder colour or gradient. - The real
srcis not set until the image is within about 200px of the viewport. - The box reserves its final size before loading, so nothing jumps when the photo arrives.
- Fade in on
load; onerrorshow a message and a Retry button. - Demo: a feed of 8 photos with a "Requested X of 8" counter; one photo is deliberately broken.
What a strong answer should cover:
IntersectionObserverwith arootMarginto start loading slightly early, one observer per image or one shared, and disconnecting it once the image is requested and on unmount.- An explicit status model (idle, loading, loaded, error) instead of several loose booleans.
- Reserving space with
width/heightoraspect-ratioto avoid layout shift (CLS), plus a low-quality placeholder. - Handling
loadanderror, and a retry that really requests the file again. - A fallback when
IntersectionObserverdoes not exist, and knowing that nativeloading="lazy"covers the simple case. - Accessibility: a real
alt,aria-busywhile loading, and an announced error.
Clarifying questions expected:
- "Is native
loading="lazy"acceptable, or do you need custom thresholds, placeholders and status callbacks?" - "How early should loading start, and is the feed scrolled by the window or by an inner container?"
- "Do we know each image's dimensions up front, so the box can reserve its size?"
Code / implementation expected: Yes. A working component in your chosen framework with the observer, placeholder, fade-in, error state and cleanup.