Startup fetches every track before any view asks for it (20.5 MB, ~170 MB transient in Go) #280

Open
opened 2026-10-06 02:40:28 +00:00 by yonlu · 1 comment
Owner

library-store fetches tracks, albums, artists and genres at DOMContentLoaded and again after every invalidation (eagerFetch()), whichever view is showing.

Measured on a 26 138-track library (desktop dev build, 2026-10-05), landing on Home, which needs none of it:

binding at startup bytes
GetTracks 20.50 MB
GetAlbums 0.77 MB
GetArtists 0.12 MB
GetGenres 0.01 MB

GetTracks alone allocates ~170 MB transient in the Go process (sqlcgen.GetTracks 80 MB, json/v2 128 MB, slices.Grow 77 MB, bytes.Clone 47 MB — alloc_space), which leaves the heap at 212 MB HeapSys and the process at 523 MB RSS; WebKitWebProcess peaks at 390 MB parsing it.

The eager fetch exists because views took seconds to open when they fetched on mount. That cost is the payload's size, not the timing (see the payload issue), and the other reason — path lookups need the whole array — is the track-cache issue.

Proposed

  • Fetch a collection when something asks for it, never at startup.
  • Prefetch on intent: pointer hover / keyboard focus on a nav item (fine pointers only), and on idle after first paint for the small collections.
  • On invalidation, refetch only collections that something is currently subscribed to; mark the rest stale.
  • An e2e spec asserts landing on Home makes no GetTracks-family call.

Blocked by the track-cache issue (removing the eager fetch before that lands breaks the openers).

`library-store` fetches tracks, albums, artists and genres at `DOMContentLoaded` and again after every invalidation (`eagerFetch()`), whichever view is showing. Measured on a 26 138-track library (desktop dev build, 2026-10-05), landing on Home, which needs none of it: | binding at startup | bytes | |---|---| | `GetTracks` | 20.50 MB | | `GetAlbums` | 0.77 MB | | `GetArtists` | 0.12 MB | | `GetGenres` | 0.01 MB | `GetTracks` alone allocates ~170 MB transient in the Go process (`sqlcgen.GetTracks` 80 MB, `json/v2` 128 MB, `slices.Grow` 77 MB, `bytes.Clone` 47 MB — `alloc_space`), which leaves the heap at 212 MB `HeapSys` and the process at 523 MB RSS; `WebKitWebProcess` peaks at 390 MB parsing it. The eager fetch exists because views took seconds to open when they fetched on mount. That cost is the payload's size, not the timing (see the payload issue), and the other reason — path lookups need the whole array — is the track-cache issue. ### Proposed - Fetch a collection when something asks for it, never at startup. - Prefetch on *intent*: pointer hover / keyboard focus on a nav item (fine pointers only), and on idle after first paint for the small collections. - On invalidation, refetch only collections that something is currently subscribed to; mark the rest stale. - An e2e spec asserts landing on Home makes no `GetTracks`-family call. Blocked by the track-cache issue (removing the eager fetch before that lands breaks the openers).
yonlu self-assigned this 2026-10-06 02:40:42 +00:00
yonlu added the
Status
In Progress
label 2026-10-06 02:40:42 +00:00
Author
Owner

Plan 023 (scoped library payloads), in order 279 → 281 → 280 → 282, then 283 and 284. Measured before/after with make perf against the bulk seed.

Plan 023 (scoped library payloads), in order 279 → 281 → 280 → 282, then 283 and 284. Measured before/after with make perf against the bulk seed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: yonlu/yellowjacket#280