perf: reduce conversation viewer render time by up to 99% - #271
Open
ChakornK wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The conversation viewer rebuilt its entire transcript on every frame.
buildContentLines()re-wrapped and re-truncated every line of every message on every render, and again on every scroll event. The per-message Markdown cache from #259 skips parsing, but nothing cached the assembled lines. At thousands of lines, it becomes extremely costly to render (~200ms/frame) and is guaranteed to go over the frame time budget. The viewer subscribes to the session, so a running agent redraws on every token and pays this cost continuously.What changed
Cache the render, not just the parse.
ConversationViewergains acontentCache, aWeakMapkeyed by the message object holding that message's rendered block (header + body, lines pre-truncated). Three things invalidate an entry: terminal width, markdown mode, or the message text. A streaming append rebuilds only the streaming message.buildContentLines()is now an assembly loop over cached blocks plus separators. The per-role rendering moved intomessageLines(), which runs only on a cache miss.Performance
Results from
npm run bench:ab -- master:Testing
npm run lint: cleannpm run typecheck: cleannpm run test: 2129 passed, 7 skippednpm run build: clean