perf: inline SVGs, memoize grid slices, batch store notifications

- Replace wa-icon shadow DOM with inline SVG in queue-panel (xmark)
  and album-dropdown (fav icons) to eliminate per-item shadow roots
- Memoize getBeforeEntries/getAfterEntries in cover-grid to prevent
  .slice() creating new array refs that trigger virtualizer relayout
- Remove transition: scale and border-radius from album cards to
  avoid per-frame repaints and anti-aliased path clipping
- Add queueMicrotask batching to player-store and favorites-store
  notify() to coalesce rapid-fire updates into single renders
This commit is contained in:
2026-03-15 09:29:40 -04:00
parent 54df917ffd
commit a4eac394ce
6 changed files with 75 additions and 25 deletions
@@ -253,6 +253,13 @@ export class CoverGrid
private gridEntriesCache: GridEntry[] = [];
private gridEntriesCacheKey: library.Album[] = [];
// getBeforeEntries/getAfterEntries memoization — prevents .slice()
// from creating new array refs that trigger virtualizer relayout.
private beforeEntriesCache: GridEntry[] = [];
private afterEntriesCache: GridEntry[] = [];
private splitEntriesCacheKey: GridEntry[] | null = null;
private splitEntriesCacheIndex = -1;
static override styles = coverGridStyles;
/* ====================================================================
@@ -909,19 +916,31 @@ export class CoverGrid
return entries;
}
/** Entries for the "before" virtualizer. */
private getBeforeEntries(): GridEntry[] {
return this.buildGridEntries().slice(
0,
this.splitIndex,
);
/** Rebuild before/after caches if the entries or splitIndex changed. */
private ensureSplitCache(): void {
const entries = this.buildGridEntries();
if (
entries === this.splitEntriesCacheKey &&
this.splitIndex === this.splitEntriesCacheIndex
) {
return;
}
this.splitEntriesCacheKey = entries;
this.splitEntriesCacheIndex = this.splitIndex;
this.beforeEntriesCache = entries.slice(0, this.splitIndex);
this.afterEntriesCache = entries.slice(this.splitIndex);
}
/** Entries for the "after" virtualizer. */
/** Entries for the "before" virtualizer (memoized). */
private getBeforeEntries(): GridEntry[] {
this.ensureSplitCache();
return this.beforeEntriesCache;
}
/** Entries for the "after" virtualizer (memoized). */
private getAfterEntries(): GridEntry[] {
return this.buildGridEntries().slice(
this.splitIndex,
);
this.ensureSplitCache();
return this.afterEntriesCache;
}
/* ====================================================================