From cd443b974bc366819c7c557ab1b0974a38408072 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Wed, 11 Feb 2026 22:57:25 -0800 Subject: [PATCH] perf(player): debounce localStorage persistence Wrap save() in a 300ms debounce to prevent rapid serialization when multiple state changes fire in quick succession (e.g. removing several items or adjusting volume). --- src/lib/player/store.svelte.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/player/store.svelte.ts b/src/lib/player/store.svelte.ts index b37ec15..b66ec1b 100644 --- a/src/lib/player/store.svelte.ts +++ b/src/lib/player/store.svelte.ts @@ -26,6 +26,9 @@ class PlayerStore { isMuted = $state(false); uiOpen = $state(false); // Mobile UI state + // Debounce timer for save() + private _saveTimer: ReturnType | null = null; + // O(1) index: track.id → index in queue private idToIndex = $derived.by(() => { const map = new Map(); @@ -99,6 +102,7 @@ class PlayerStore { } save() { + // Read snapshots synchronously so $effect tracks reactive deps const data: PlayerState = { queue: $state.snapshot(this.queue), currentId: $state.snapshot(this.currentId), @@ -109,7 +113,11 @@ class PlayerStore { volume: $state.snapshot(this.volume), isMuted: $state.snapshot(this.isMuted), }; - localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); + // Debounce only the serialization + write + if (this._saveTimer) clearTimeout(this._saveTimer); + this._saveTimer = setTimeout(() => { + localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); + }, 300); } // Actions