Challenge 2: Choose Native vs IntersectionObserver — Possible Solution ==================================================================== SCENARIO: Offscreen images need to fade in smoothly with a custom animation as they load, well before native loading="lazy"'s default threshold. RECOMMENDATION: IntersectionObserver-based lazy loading JUSTIFICATION (using this chapter's tradeoffs) -------------------------------------------------- - Custom threshold requirement: the chapter explicitly notes that IntersectionObserver-based loading is needed "mainly for advanced behavior the native attribute doesn't offer" — and controlling exactly WHEN (how far before the viewport) an image starts loading is precisely this kind of behavior. Native loading="lazy" gives the browser's own built-in judgment about when to start fetching, with no way for a developer to configure that threshold to fire earlier or later than the browser's default. - Custom fade-in animation requirement: a smooth fade-in effect as an image loads requires JavaScript to be involved at the right moment — swapping a placeholder for the real image, toggling a CSS class, triggering a transition. Native loading="lazy" is a pure browser-level fetch-deferral mechanism with no hook for custom behavior layered on top of the loading moment itself; IntersectionObserver, by contrast, gives a JavaScript callback that fires at exactly the right time to drive this kind of animation. - The chapter's own tradeoff, honestly acknowledged: choosing IntersectionObserver here does mean accepting some JS running on the main thread (a Chapter 4 concern) that the native attribute avoids entirely. This is a real cost, but it's the necessary cost of the specific, non-negotiable requirements in this scenario (custom threshold + custom animation) — requirements the simpler native option has no way to satisfy at all, regardless of how that JS cost is managed. WHY THIS WORKS AS A DECISION -------------------------------- This mirrors the chapter's own framing directly: reach for IntersectionObserver specifically when a requirement genuinely exceeds what the native attribute offers, not by default. Here, BOTH stated requirements (earlier threshold, custom animation) are things the native attribute structurally cannot do, making this one of the legitimate cases the chapter describes IntersectionObserver as being "needed" for — not a case where reaching for the more complex option would be premature or unnecessary.