feedBack/static/v3
ChrisBeWithYou c7aa5a10b0
fix(v3): recycle library grid cards on scroll instead of rebuilding the window (#742)
The virtualized v3 Songs grid rebuilt its entire visible window
(grid.innerHTML = _renderCardsRange(...) + a full wireCards pass) every
time it slid by one row. Each row-boundary crossing was therefore a heavy
synchronous frame — reparse ~60 cards, re-attach hundreds of listeners,
reflow — that stalled the main thread and buffered held-arrow key-repeats,
flushing them in a burst. Testers saw the library "go super fast for a
second then slow down," skipping "every so many scrolls," up or down, at
the same spots each time. It hitched scrolling back up over already-loaded
songs too, because the cost was DOM teardown, not fetching.

renderWindow() now reconciles the window in place: it reuses the card
nodes that stay on-screen and builds only the row that enters/leaves
(~6 nodes per slide instead of ~60). Nodes are keyed by absolute index
(data-idx) with a real-vs-skeleton + select-mode signature (data-sig) so
hole-fills after a page fetch and select-mode toggles still rebuild
exactly the nodes that changed. wireCards()'s existing data-wired guard
then wires only the freshly-built nodes, so per-slide listener churn drops
with it. Everything keyed off data-fn (favorites, ⋮ menu, right-click,
selection, accuracy badges, A–Z rail) is unaffected.

Follow-up to the stage-2 virtualized grid (#636 item 3). Frontend-only.

Tests: tests/js/v3_songs_window_recycle.test.js — window stays [start,end)
contiguous and in-window node identity is reused across a down-then-up
scroll; select-mode toggle and a rail-seek jump rebuild correctly.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
2026-07-05 00:19:46 +02:00
..
avatars Clean release snapshot 2026-06-16 18:47:13 +02:00
brand feat(v3): use PNG logo in sidebar nav instead of the text wordmark (#734) 2026-07-03 11:39:27 +02:00
pedals Clean release snapshot 2026-06-16 18:47:13 +02:00
audio-routing.js feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
badges.js settings: add host instrument profiles (#753) 2026-07-05 00:16:42 +02:00
brand.js Clean release snapshot 2026-06-16 18:47:13 +02:00
card-actions-core.js v3 library: song Details drawer + bulk edit — P2 (#703) 2026-07-02 13:29:05 +02:00
dashboard.js feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
feedbarcade.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
image-picker.js v3 library: multi-candidate cover picker — select from a populated list (#732) 2026-07-03 08:49:44 +02:00
index.html feat(enrichment): AcoustID audio-fingerprint identification (opt-in) (#759) 2026-07-05 00:17:43 +02:00
interface-size-nudge.js feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
interface-size-ui.js feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
lessons.js feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
live-guitar-tone-source.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
live-performance-hud.js fix(v3): reset live performance HUD on backward seek / restart (#607) 2026-06-27 00:47:43 +02:00
manifest.json Clean release snapshot 2026-06-16 18:47:13 +02:00
match-review.js feat(enrichment): AcoustID audio-fingerprint identification (opt-in) (#759) 2026-07-05 00:17:43 +02:00
notifications.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
onboarding-tour.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
overlay-active.png Clean release snapshot 2026-06-16 18:47:13 +02:00
overlay-inactive.png Clean release snapshot 2026-06-16 18:47:13 +02:00
pedal-cables.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
pedal-default.svg Clean release snapshot 2026-06-16 18:47:13 +02:00
pedal-frame.svg Clean release snapshot 2026-06-16 18:47:13 +02:00
player-chrome.js review: address PR #694 findings 2026-07-02 00:35:24 +02:00
playlists.js fix(v3): keep shuffle toggle size stable across states 2026-07-03 14:10:16 +02:00
plugins-page.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
profile.js feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
progress.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
progression-core.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
scoreboard-pref.js fix(highway): user-selectable scoreboard to stop duplicate HUDs 2026-06-19 20:56:38 +02:00
settings.js settings: add host instrument profiles (#753) 2026-07-05 00:16:42 +02:00
shell.js feat(v3): use PNG logo in sidebar nav instead of the text wordmark (#734) 2026-07-03 11:39:27 +02:00
shop.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
songs.js fix(v3): recycle library grid cards on scroll instead of rebuilding the window (#742) 2026-07-05 00:19:46 +02:00
stats-recorder.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
theme-core.js feat(v3): host theme read surface — window.feedBack.theme + always-present --fbv-* tokens (#646) 2026-07-02 13:57:58 +02:00
tuner-core.js Clean release snapshot 2026-06-16 18:47:13 +02:00
v3.css feat(a11y): app-wide "Interface size" setting (Accessibility) (#664) 2026-07-02 14:00:30 +02:00
venue-instrument-pov.js Clean release snapshot 2026-06-16 18:47:13 +02:00
venue-mood-fx.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
venue-scene-3d.js rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
venue-viz.js Clean release snapshot 2026-06-16 18:47:13 +02:00