Thanks to visit codestin.com
Credit goes to github.com

Skip to content

toolpath-desktop: memoize markdown rendering per chat turn #38

@eliothedeman

Description

@eliothedeman

Follow-up from #34 review. Perf concern, not a correctness bug.

ChatView.svelte calls renderMarkdown(t.text) inline inside the {#each turns} block on every reactive tick. In a 1700-step Claude session, that can be 500+ assistant turns × [marked.parse + DOMPurify.sanitize] per re-render. Svelte 5's $derived won't memoize across this loop; the pipeline re-runs whenever any unrelated state mutates preview (tree-query typing, selection change, view-mode toggle).

Fix

Cache the rendered HTML on the ChatTurn itself at flatten time, so subsequent renders are a trivial property read:

// in tree.ts::flattenChatHead
const textHtml = c.text ? renderMarkdown(c.text) : "";
const thinkingHtml = c.thinking ? renderMarkdown(c.thinking) : "";
// → store on ChatTurn, use in ChatView without re-calling renderMarkdown

This changes flattenChatHead from classify-only to render-too, which couples it to the markdown pipeline — acceptable given ChatTurn is a UI-model type.

Alternative: Map<stepId, string> memo external to the flatten, keyed by step.id + text hash.

Same treatment wanted

  • diff.raw.split("\n") in the tool block — cache the split on the turn.
  • viz.ts::renderCard also calls renderMarkdown(bodyText) for graph cards on every render(). Graph re-renders are less frequent but not free.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions