A media-heavy single-page application used IntersectionObserver for lazy loading media assets during smooth scroll navigation. However, the implementation triggered unnecessary loading of intermediate sections, wasting bandwidth and causing visual inconsistencies.
Issue
Menu navigation with smooth scrolling caused IntersectionObserver to load all intermediate sections, consuming 20-30MB of bandwidth per click by loading unnecessary media files. Additionally, skipping intermediate sections led to empty media containers when manually scrolling back, as the IntersectionObserver failed to re-fire for skipped elements.
Culprit
The aggressive configuration of rootMargin combined with smooth scroll animations caused the viewport to pass through all intermediate sections, triggering the IntersectionObserver to load content unnecessarily. Skipping intermediate sections prevented loading but also prevented the observer from re-firing when manually scrolling back to those sections.
Solution
State Management
A state management system was introduced to track navigation state, including the target section and skipped elements, ensuring deferred processing of intermediate sections.
Reusable Loading Logic
The lazy loading logic was extracted into a reusable function with features such as local storage caching for presigned URLs, S3 key validation, and consistent fade-in behavior.
Enhanced Observer Callback
The IntersectionObserver callback was modified to store skipped elements instead of silently skipping them, allowing for later reprocessing when manually scrolling back.
Deferred Processing
A deferred processing mechanism was added to re-process skipped elements after the scroll animation completes. This ensures that manually scrolling back to previously skipped sections loads the media as expected.
Performance Impact
- Reduced bandwidth usage by over 95%, from 20-30MB to approximately 1MB per navigation.
- Maintained instant loading of destination content.
- Restored full functionality for manual scrolling.
- Added protection against rapid-click events to ensure smooth operation.