From 584eae6e0bf00a603fba946e76544bbaf3476415 Mon Sep 17 00:00:00 2001 From: patch Date: Fri, 23 Oct 2026 13:20:17 +0200 Subject: [PATCH] perf(cli): render one smaller page of transcript messages A re-render lays out every rendered node, and the cost is linear in that count whether or not the node changed: an unchanged 1,500-node transcript measures ~60ms per frame against ~0.1ms when nothing re-renders, so memoizing cannot rescue it and a streamed chunk re-renders the whole page. At the real density (~770 nodes per message) one page of 15 messages costs ~266ms per frame against ~104ms for six, so a long conversation falls behind its own output. LoadPreviousButton already offers the rest of the history, so the smaller page trades a click of history for frames that keep up with the stream. --- cli/src/hooks/use-chat-messages.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/cli/src/hooks/use-chat-messages.ts b/cli/src/hooks/use-chat-messages.ts index 09b611f766..16724f95a9 100644 --- a/cli/src/hooks/use-chat-messages.ts +++ b/cli/src/hooks/use-chat-messages.ts @@ -13,8 +13,21 @@ import { buildMessageTree } from '../utils/message-tree-utils' import type { ChatMessage, ContentBlock } from '../types/chat' -/** Batch size for message pagination */ -const MESSAGE_BATCH_SIZE = 15 +/** + * Batch size for message pagination. + * + * This is a frame-cost knob, not a layout preference. A re-render lays out + * every rendered node, and the cost is linear in that count whether or not the + * node changed — an unchanged 1,500-node transcript measures ~60 ms per frame + * against ~0.1 ms when nothing re-renders, so memoizing cannot rescue it. A + * streamed chunk re-renders the whole page, which is why a long conversation + * used to fall behind its own output. + * + * One page at 15 messages measured ~11.5k nodes and ~60 ms per frame; six + * costs roughly a third of that. `LoadPreviousButton` already offers the rest, + * so the trade is one click of history for frames that keep up with the stream. + */ +const MESSAGE_BATCH_SIZE = 6 /** * Options for useChatMessages hook.