mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-11 02:14:29 +00:00
1787e192137889a6e1a64e2d5d54b386dd4c48e9
A song list rendered EVERY song it held. On a flat 50,944-song library that is
one <div> with 50,938 children and ~1,300,000 DOM nodes — ~4.2 GB of renderer
RSS, for a screen the user may not even be looking at (it was built while the
visible screen was v3-home).
It is not just this plugin's problem. A million-node document poisons unrelated
code: any `document.querySelector` that MISSES has to walk the whole tree before
returning null. That is exactly how song_preview's per-frame menu check ended up
consuming ~50% of the renderer and dropping the app to 2.7 fps
(feedBack-plugin-song-preview#7 fixes the per-frame walk; this fixes the tree it
was walking).
So render only what is on screen. Rows are uniform height (grid cards uniform
size), so the window is pure arithmetic — no per-row observers. Off-window songs
are represented by padding ON THE LIST rather than spacer elements: a spacer div
would become a grid ITEM in grid view and shift the columns, whereas padding
behaves identically in both layouts. Lists at or below VIRTUAL_MIN (200) render
in full exactly as before, so normal folders are untouched.
Two ordering fixes this forced, both real bugs waiting to happen:
- Both expand handlers populated the list BEFORE showing it. A windowed list
measures a real row and the scroller viewport, and both are zero under
display:none. Show first, then populate.
- _render() now tears down the previous render's scroll listeners. Without it
they survive against detached nodes and leak on every re-render.
Verified in real Chromium over CDP with 50,000 rows — the DOM glue, not just the
maths:
at top rendered= 25 rows scrollHeight=2,200,000px [0..24]
scroll 500k rendered= 31 rows scrollHeight=2,200,000px [11357..11387]
scroll 1,100k rendered= 31 rows scrollHeight=2,200,000px [24994..25024]
scroll to end rendered= 25 rows scrollHeight=2,200,000px [49975..49999]
25-31 rows in the DOM instead of 50,000; scroll height exact and constant (the
scrollbar stays honest); the last row lands on song 49,999.
Tests: _visibleWindow is pure and exposed via __test — top/middle/bottom/past-
the-end windows, the grid row-packing case, the padding-plus-rendered-equals-
total invariant that keeps the list from changing height as you scroll, and the
degenerate zero-height case (a list still display:none) falling back to
render-everything rather than to an empty list. eslint clean; full JS suite
1186/1186.
Languages
JavaScript
56.4%
Python
37.1%
HTML
3.2%
CSS
1.2%
TypeScript
1.1%
Other
1%