Summary
MarkdownBlock hands the entire accumulated msg.content to SolidMarkdown on every streaming delta, so each chunk re-runs a full unified() markdown parse and (with the default renderingStrategy: "memo") tears down and rebuilds the message's entire rendered DOM subtree. O(L²) parse cost plus per-chunk DOM churn over a stream.
Location
web/src/components/transcript/MessageRow.tsx:111-117 (also plans at :226)
- solid-markdown
generateNode memo re-parses the whole string; every hast node is a fresh object so Solid's <For> recreates the subtree.
Failure scenario
A long assistant answer (10–20 KB with tables/code) streaming at 20–40 deltas/s visibly stutters the tab and pegs a core; it gets worse the longer the answer runs.
Fix
Throttle content into the renderer (batch deltas per animation frame), and/or switch to renderingStrategy: "reconcile", and/or split the message into memoized markdown blocks so only the tail block re-parses. Pairs with the streaming-reducer O(N) scan issue.
Summary
MarkdownBlockhands the entire accumulatedmsg.contenttoSolidMarkdownon every streaming delta, so each chunk re-runs a fullunified()markdown parse and (with the defaultrenderingStrategy: "memo") tears down and rebuilds the message's entire rendered DOM subtree. O(L²) parse cost plus per-chunk DOM churn over a stream.Location
web/src/components/transcript/MessageRow.tsx:111-117(also plans at:226)generateNodememo re-parses the whole string; every hast node is a fresh object so Solid's<For>recreates the subtree.Failure scenario
A long assistant answer (10–20 KB with tables/code) streaming at 20–40 deltas/s visibly stutters the tab and pegs a core; it gets worse the longer the answer runs.
Fix
Throttle content into the renderer (batch deltas per animation frame), and/or switch to
renderingStrategy: "reconcile", and/or split the message into memoized markdown blocks so only the tail block re-parses. Pairs with the streaming-reducer O(N) scan issue.