perf: freeze detached chat history updates

Stop historical chat view from waking on live tail deltas by suspending detached part updates, narrowing scroll manager dependencies, and hardening sync-context HMR behavior during dev.
This commit is contained in:
Bohdan Triapitsyn
2026-04-05 15:58:06 +03:00
parent 4663abd6f3
commit e56f2f99cf
4 changed files with 50 additions and 20 deletions
@@ -32,6 +32,7 @@ import { useSessionUIStore } from '@/sync/session-ui-store';
import { useViewportStore } from '@/sync/viewport-store';
import { useStreamingStore } from '@/sync/streaming';
import {
useSessionMessageCount,
useSessionMessageRecords,
useSessions,
useDirectorySync,
@@ -295,8 +296,12 @@ export const ChatContainer: React.FC = () => {
[currentSessionId],
),
);
const sessionMessageCount = useSessionMessageCount(currentSessionId ?? '');
const [suspendDetachedTailUpdates, setSuspendDetachedTailUpdates] = React.useState(false);
// Messages from sync system
const sessionMessageRecords = useSessionMessageRecords(currentSessionId ?? '');
const sessionMessageRecords = useSessionMessageRecords(currentSessionId ?? '', undefined, {
suspendPartUpdates: suspendDetachedTailUpdates,
});
const sessionMessages = currentSessionId ? sessionMessageRecords : EMPTY_MESSAGES;
// Sessions from sync system
@@ -475,7 +480,7 @@ export const ChatContainer: React.FC = () => {
isProgrammaticFollowActive,
} = useChatScrollManager({
currentSessionId,
sessionMessages,
sessionMessageCount,
streamingMessageId,
sessionMemoryState: sessionMemoryStateMap,
updateViewportAnchor,
@@ -486,6 +491,11 @@ export const ChatContainer: React.FC = () => {
onActiveTurnChange: handleActiveTurnChange,
});
React.useEffect(() => {
const next = Boolean(currentSessionId && streamingMessageId && !isPinned);
setSuspendDetachedTailUpdates((previous) => (previous === next ? previous : next));
}, [currentSessionId, isPinned, streamingMessageId]);
const viewportMessagesRef = React.useRef<SessionMessageRecord[]>(EMPTY_MESSAGES);
const viewportSessionIdRef = React.useRef<string | null>(null);
const viewportMessages = React.useMemo(() => {