You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
perf(tui): terminal resize re-renders the full transcript; cost scales with session size #54112
Resizing the terminal with a big session open feels sluggish, so I dug in to see what actually happens per resize. Turns out the whole transcript gets re-evaluated every time.
In packages/tui/src/routes/session/index.tsx, messages() reads the full store with no slicing, then <For each={messages()}> renders every message, each rendering all of its parts, each text part going through <markdown>. On top of that, width-dependent memos (like the tool-output collapse) all recompute through useTerminalDimensions. Nothing is virtualized.
I measured it with a testRender harness (transcript-shaped tree, resize across a few widths). Median per-resize cost:
50 parts → ~17 ms
500 parts → ~23 ms
2000 parts → ~94 ms
So it's O(session) per frame. Full numbers in the gist.
Two related things I ran into in the same area:
Past a few thousand markdown/code renderables in one tree, the native side throws Failed to create native renderable (via TextBufferRenderable <- Code <- Markdown:updateBlocks). Looks like a finite FFI handle pool, so very large histories can hit a hard ceiling just by rendering.
To be clear about what this is not: per-resize terminal output is screen-bounded (around 10 KB per frame against a real 52 MB session, bit-identical per width, TUI RSS flat over 30 resizes). So this is purely a responsiveness/perf issue, not a memory blowup. Filing as perf only.
Possible directions: virtualize the transcript (viewport + overscan), truncate large part bodies in the transcript view, and port cleanupSessionCaches() over to the TUI store. Happy to PR the test harness as packages/tui/test/context/resize-cost.test.tsx plus the store eviction if that sounds reasonable.
Thanks for the detailed measurements and the gist! To restate the request: the v2 TUI should not re-render the whole transcript on every terminal resize, so that resize cost stays bounded by the viewport instead of growing with session size. You suggest viewport virtualization with overscan, truncating large part bodies in the transcript view, and evicting cached store data.
One note from the current v2 code: routes/session/index.tsx does slice rows (visibleRows via hidden()/visibleRowsEnd), but that only hides older history. It is not a viewport window, so every row that is shown still mounts all its parts and markdown, and the width-dependent memos all recompute on resize. Your core observation holds.
Maintainers will consider this; I can't promise anything about whether or when. Related issues:
If you open a PR for the resize-cost harness or the store eviction, linking it here (and to #39380 if it's relevant) will help maintainers review it alongside the virtualization question.
Activity
opencode-agent commentedon Oct 9, 2026
Thanks for the detailed measurements and the gist! To restate the request: the v2 TUI should not re-render the whole transcript on every terminal resize, so that resize cost stays bounded by the viewport instead of growing with session size. You suggest viewport virtualization with overscan, truncating large part bodies in the transcript view, and evicting cached store data.
One note from the current
v2code:routes/session/index.tsxdoes slice rows (visibleRowsviahidden()/visibleRowsEnd), but that only hides older history. It is not a viewport window, so every row that is shown still mounts all its parts and markdown, and the width-dependent memos all recompute on resize. Your core observation holds.Maintainers will consider this; I can't promise anything about whether or when. Related issues:
message.removedbug in the same store area as your cleanup point.dev), so whether the v2 TUI store has the same gap should be checked separately.If you open a PR for the resize-cost harness or the store eviction, linking it here (and to #39380 if it's relevant) will help maintainers review it alongside the virtualization question.