From 78186486c56a162e6a8bc54fac386c00b842f041 Mon Sep 17 00:00:00 2001 From: TerryM Date: Mon, 8 Jun 2026 01:23:53 +0800 Subject: [PATCH] fix(stream): keep previous items visible while refetching on locale switch Root cause of the "Bahasa Melayu lags then shows" report: switching locale invalidates the cache key in usePostStream (streamKey includes lang), the effect that handles dep changes calls `setItems([])` before `fetchPage(true)`, and that blanks the entire stream for the duration of the network round-trip (~150-300ms in dev). The earlier fixes (AnimatePresence key, font stack, useLayoutEffect title sync) addressed visible side effects, but this blank window is the actual source of the perceived freeze. Drop the eager reset. fetchPage(true) replaces items wholesale once the new locale's response arrives, so leaving the previous list in place is a stale-while-revalidate swap: visible content during the gap, single replace at the end, no skeleton flash, no scroll jump. Verified in browser with a cn -> ms switch: mainTextLen never hits zero during the transition, and the new list takes over at t~120ms without an intervening blank frame. --- src/components/messageStream/hooks/usePostStream.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/messageStream/hooks/usePostStream.ts b/src/components/messageStream/hooks/usePostStream.ts index 646de1f..0d267f0 100644 --- a/src/components/messageStream/hooks/usePostStream.ts +++ b/src/components/messageStream/hooks/usePostStream.ts @@ -288,7 +288,11 @@ export function usePostStream(params: PostStreamParams): PostStreamResult { return; } restoredFromCacheRef.current = false; - setItems([]); + // Stale-while-revalidate: keep showing whatever items were on screen for + // the previous params (e.g. previous locale) while the new fetch runs. + // Clearing to [] here was the root cause of the language-switch flicker + // — the stream went blank between the click and the network response. + // fetchPage(true) below will replace items wholesale once data arrives. cursorRef.current = undefined; setHasMore(true); hasMoreRef.current = true;