Skip to content

perf(ui): avoid building collapsed tool card content on mount - #14012

Merged
marius-kilocode merged 1 commit into
mainfrom
benchmark-vscode-tool-rendering-performance
Sep 10, 2026
Merged

marius-kilocode merged 1 commit into
mainfrom
benchmark-vscode-tool-rendering-performance

Conversation

@marius-kilocode

Copy link
Copy Markdown
Collaborator

What Problem This Solves

Mounting a VS Code tool card did a large amount of work for content the user could not see. The card's collapsed body was constructed on mount even while closed, so Markdown and tool output parsing ran and were then discarded.

Why This Change Was Made

BasicTool.hasChildren() read props.children to test for presence:

const hasChildren = () => (props.defer ? "children" in props : props.children)

In Solid, props.children is a getter. Reading it evaluates the child expression, which builds the entire collapsed body subtree. A CPU profile of mounting grep cards showed checksum, marked's regexes, updateBlock, and DOMPurify.sanitize as the top self-time, while the DOM contained zero mounted tool outputs. The work was done and thrown away.

The fix checks for presence without evaluating, matching the branch the component already used when defer was set. The collapsed body is then constructed only when it is actually rendered.

User Impact

Tool cards mount faster and the transcript stays more responsive while tools stream. There is no visual change: collapsed cards still expand to the same content, and the reveal and expand animations are untouched.

Evidence

Per-card collapsed mount, 40 real cards rendered with the production components:

Tool Before After Change
grep 1.363 ms 0.667 ms -51%
glob 1.180 ms 0.665 ms -44%
bash 2.967 ms 2.045 ms -31%
todowrite 7.022 ms 3.660 ms -48%
reasoning 1.643 ms 1.680 ms ~0
read 0.618 ms 0.578 ms ~0

Tools whose bodies hold content improve; tools that already deferred or had no body are unchanged. That split confirms the fix targets the eager construction rather than general mount cost.

Limitation: these are controlled mounts of the real components, not a full interactive agent session. The gain scales with how many content-bearing cards a session mounts.

Verification

  • packages/ui: typecheck and unit tests pass.
  • packages/kilo-vscode: typecheck, lint, knip, and the full unit suite pass.
  • A new test mounts the real BasicTool, asserts a collapsed card does not construct its body, and asserts the body is built once when expanded.

@kilo-code-bot

kilo-code-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (4 files)
  • .changeset/readable-tool-mounts.md
  • packages/kilo-vscode/tests/fixtures/basic-tool-render.tsx
  • packages/kilo-vscode/tests/unit/basic-tool-render.test.ts
  • packages/ui/src/components/basic-tool.tsx

Reviewed by grok-4.6 · Input: 204.8K · Output: 18.2K · Cached: 520.6K

Review guidance: REVIEW.md from base branch main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants