From 9b12a282af51a4c19d999754292a6648e8669377 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:47:27 -0400 Subject: [PATCH] perf(watch-history): show persisted history instantly on reload After a page reload the in-memory caches (service fingerprintCache and the client watch-history cache) are empty, so loadLatest's non-blocking path returned [] and the For You feed suppressed nothing until the slow background network refresh (~150 encrypted chunk events over 2 sequential relay round-trips) landed. Return the best available items immediately via getCachedSnapshotItems, which falls back to the persisted localStorage snapshot. Reloads now suppress watched videos right away using the last-known history, while the background refresh still runs and corrects it (firing "fingerprint" to re-run the feed). Persisted items were previously valid, so there is no correctness risk. Co-Authored-By: Claude Opus 4.8 --- js/watchHistoryService.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/js/watchHistoryService.js b/js/watchHistoryService.js index b3bfafdc..f093c24e 100644 --- a/js/watchHistoryService.js +++ b/js/watchHistoryService.js @@ -1301,15 +1301,21 @@ async function loadLatest(actorInput, options = {}) { ); refreshPromise.catch(() => {}); + // Return the best available items immediately — in-memory cache, else the + // persisted localStorage snapshot. The in-memory caches are empty after a page + // reload, so without the persisted fallback the For You feed would suppress + // nothing until the (slow) background network refresh completes. Persisted + // items were previously valid; the background refresh corrects them. + const immediateItems = getCachedSnapshotItems(actorKey); devLogger.info( "[watchHistoryService] Returning immediately; watch history refreshing in background.", { actor: actorKey, - itemCount: cacheEntry?.items?.length || 0, + itemCount: immediateItems.length, } ); - return mergeQueuedItemsIfNeeded(actorKey, cacheEntry?.items || []); + return mergeQueuedItemsIfNeeded(actorKey, immediateItems); } async function getFingerprint(actorInput) {