perf: bound the renderer-side VOD storyboard cache (FIFO 100)
vodStoryboardClientCache was a plain Map<vodId, VodStoryboard | null> with no eviction. Every VOD ever hovered cached its first sprite data URL — about 50-200 KB each. Browsing a long-running streamer's 2000-VOD archive could leave the renderer holding 100-400 MB of hover-only sprite data permanently, with no signal to the user that it was happening. Wrapped writes in a rememberStoryboard helper that caps the cache at 100 entries with FIFO eviction (Map iterator is insertion-ordered so .keys().next().value is always the oldest). Cache hit / miss semantics unchanged for the live set — only the dropped-off-the- back entries get re-fetched if the user scrolls back to a VOD they hovered hundreds of cards ago, and that re-fetch is fast because the main-process side has its own metadata cache that survives the renderer-side eviction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
96683afa14
commit
976ca40963
@ -21,6 +21,20 @@ let pendingHoverVodId: string | null = null;
|
||||
const HOVER_DEBOUNCE_MS = 220;
|
||||
const FRAME_INTERVAL_MS = 600;
|
||||
const FRAMES_TO_CYCLE = 4;
|
||||
// Bounded cache — each storyboard data URL is ~50-200 KB, so an
|
||||
// unbounded cache could balloon to hundreds of MB on a long browsing
|
||||
// session through a streamer with thousands of VODs. FIFO eviction
|
||||
// keeps the working set fresh without manual cleanup.
|
||||
const MAX_CLIENT_STORYBOARD_CACHE = 100;
|
||||
|
||||
function rememberStoryboard(vodId: string, sb: VodStoryboard | null): void {
|
||||
vodStoryboardClientCache.set(vodId, sb);
|
||||
if (vodStoryboardClientCache.size > MAX_CLIENT_STORYBOARD_CACHE) {
|
||||
// Map iterator is insertion-ordered — first key is the oldest.
|
||||
const oldestKey = vodStoryboardClientCache.keys().next().value as string | undefined;
|
||||
if (oldestKey !== undefined) vodStoryboardClientCache.delete(oldestKey);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureVodHoverHandlersBound(): void {
|
||||
const grid = document.getElementById('vodGrid');
|
||||
@ -85,7 +99,7 @@ async function activateHoverPreview(card: HTMLElement, vodId: string): Promise<v
|
||||
} catch (_) {
|
||||
storyboard = null;
|
||||
}
|
||||
vodStoryboardClientCache.set(vodId, storyboard);
|
||||
rememberStoryboard(vodId, storyboard);
|
||||
}
|
||||
|
||||
// Cursor may have moved on while we awaited; re-check guard.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user