perf(web): keep chat markdown mounted while text streams - #255
Conversation
Streamed assistant text recreated the ReactMarkdown renderer map on every token, which remounted code controls and details and re-ran highlighting for unchanged fences. Named renderer types now live in a module-level map and read message state from context, so live bot and group ChatMarkdown stays mounted while the text grows.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Greptile SummaryThis update keeps Markdown renderer component identities stable as streamed chat text changes, moving message-specific data through Confidence Score: 5/5Safe to merge; the remaining test-coverage concern is non-blocking. The previous finding remains outstanding because Reviews (2): Last reviewed commit: "Merge branch 'main' into fix/web-markdow..." | Re-trigger Greptile |
| it("still renders streamed fences and details after extra trailing text", () => { | ||
| const fence = ["```text", "First code block", "```", "", "Streaming reply"].join("\n"); | ||
| const html = renderToStaticMarkup( | ||
| <ChatMarkdown cwd="/tmp/project" text={`${fence} 9`} isStreaming />, | ||
| ); | ||
|
|
||
| expect(html).toContain('data-language="text"'); | ||
| expect(html).toContain("First code block"); | ||
| expect(html).toContain("Streaming reply 9"); | ||
| }); |
There was a problem hiding this comment.
This test renders one static tree containing only a fenced code block and trailing text. It does not include <details>, change an interactive control, or rerender after text changes, so a later change that remounts markdown renderers during streaming could still pass while collapsing expanded details or resetting code controls. This is non-blocking, but add a client-rendered test that expands a details block or changes a code control, appends streamed text, and verifies the same node and its state are retained.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Artifacts
- The focused test expands markdown details, updates streamed text, and checks that the same node remains open.
Mounted-state validation command
- The saved command runs the focused mounted-state validation.
Mounted-state validation output
- The recorded output shows the focused mounted-state test passed.
|
This is Leo's agent. Independently accepted head 424f183 after full diff review, passing focused committed tests, and isolated browser checks in individual and group chats. Twelve successive client message-text updates preserved expanded details and code-node identity on each route; a separate message remained collapsed. Collapse and code-wrap controls worked. These checks used reversible client-state fixtures, not live provider streaming. The committed mounted-rerender coverage request remains valid non-blocking test debt, as the fresh Greptile review states; I am not marking it fixed or resolving the reviewer-owned thread. Required Repository checks passed. |
What Changed
ChatMarkdownno longer rebuilds its ReactMarkdown renderer map on every streamed token. Named renderer types live in a module-levelCHAT_MARKDOWN_COMPONENTSobject and read the current message throughChatMarkdownRendererContext.Live bot and group chats already use this component from
BotThreadLandingandGroupThreadLanding. Code wrap, copy, and details state can now survive trailing text updates, and unchanged fences do not remount.Why
Each token used to recreate renderer function types. React treated that as a new tree, so code-block controls reset and Shiki ran again even when the fence had not changed.
Adapted from pingdotgg/t3code#9677. Credit to that work.
UI Changes
No intended visual change. Isolated browser check: Scout bot chat still renders
ChatMarkdownfor the assistant reply, with reply/reaction/read-aloud on the liveBotThreadLandingcomposer.This fixture home had no group chat, so group-route markdown was not exercised here. The renderer is the same
ChatMarkdownpath.Checklist
Scope
react-test-renderer. Stability is guarded by a source test plus the existing ChatMarkdown suite.Verification
vp test run apps/web/src/components/ChatMarkdown.test.tsxpassed (36 tests)vp run --filter @t3tools/web typecheckpassedBotThreadLandingstill renders the assistant reply through.chat-markdownLimitations
A live streaming turn was not exercised because the fixture provider instances are disconnected. Native mobile was not run. File preview markdown uses the same component and was covered by existing tests, not a separate browser pass.
Implemented and verified by Grok 4.6 High in Grok Build via Orca.