perf(07-02): defer eagerFetch to after DOM ready for instant app shell

- Remove eagerFetch() call from LibraryStore constructor
- Add deferEagerFetch() that waits for DOMContentLoaded event
- App shell renders before backend data roundtrips begin
- All 4 data types (tracks, albums, artists, genres) still loaded eagerly
- invalidate() still calls eagerFetch() directly for post-scan refresh
This commit is contained in:
2026-03-04 20:54:38 -05:00
parent 9f381e2a03
commit cd98ad6dc8
+31 -6
View File
@@ -53,7 +53,32 @@ class LibraryStore {
}); });
this.loadCoverSize(); this.loadCoverSize();
this.eagerFetch(); this.deferEagerFetch();
}
/**
* Schedules eagerFetch() to run after the DOM is ready.
* The LibraryStore singleton is instantiated during ES module
* evaluation (import time), so calling eagerFetch() in the
* constructor would fire 4 backend roundtrips before the app
* shell has rendered. Deferring to the 'DOMContentLoaded'
* event (or calling immediately if the DOM is already parsed)
* lets the shell paint first, then begins data loading.
*/
private deferEagerFetch(): void {
if (document.readyState === 'loading') {
window.addEventListener(
'DOMContentLoaded',
() => {
this.eagerFetch();
},
{ once: true },
);
} else {
// DOM already parsed (shouldn't happen during module
// eval, but handles dynamic instantiation safely).
this.eagerFetch();
}
} }
// =================================================================== // ===================================================================
@@ -291,11 +316,11 @@ class LibraryStore {
} }
/** /**
* Fetches all library data. Called from the constructor * Fetches all library data. Called after DOM ready
* (initial load) and after cache invalidation so that * (initial load, via deferEagerFetch) and after cache
* controller subscribers receive fresh data on the next * invalidation so that controller subscribers receive
* requestUpdate() cycle without needing their own * fresh data on the next requestUpdate() cycle without
* LibraryScanComplete listener. * needing their own LibraryScanComplete listener.
*/ */
private eagerFetch(): void { private eagerFetch(): void {
void this.getTracks(); void this.getTracks();