081b2b68d8
The photos timeline rendered every tile into the DOM and grew it unbounded on infinite scroll, degrading on large libraries. Each date-group is now a <section> whose grid is materialized (tiles inserted) only while near the viewport and dematerialized (emptied, height frozen as a spacer) once it scrolls away, driven by an IntersectionObserver rooted on the scroll container. DOM nodes stay bounded by a few screens regardless of library size. - Grouping (day/month/year), infinite scroll, multi-select, video thumbnails and fade-in are all preserved. - Selection state and the video-thumbnail cache survive the materialize/dematerialize cycle. - Falls back to full rendering when IntersectionObserver is unavailable. - Spacer heights are estimated from grid geometry and re-estimated on resize. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M