Same optimization as the merged ResponseMessage PR: replace JSON.parse(JSON.stringify()) with structuredClone and add an O(1) fast-path check on content before falling back to full JSON.stringify comparison.
Same optimization as ResponseMessage: add O(1) fast-path check on content and done fields before falling back to full JSON.stringify comparison. Avoids expensive serialization when only content changes during streaming.
During streaming, every token change triggers a full JSON.stringify comparison on the code block token object. Add an O(1) fast-path check on token.text and token.raw — the fields that actually change during streaming — before falling back to the expensive JSON.stringify comparison for infrequent structural changes.
Add O(1) array length check before expensive JSON.stringify comparison. During streaming, status history typically only grows via appends, so a length mismatch catches most updates without serialization.
* perf: cache KaTeX module import as singleton across all renderer instances
KatexRenderer.svelte dynamically imports katex, mhchem, and the CSS on every component mount. When a message contains multiple math expressions, this triggers redundant module resolution for each one. Move the import promise to a module-level singleton using Svelte's context='module' script block so it loads once and is shared across all KatexRenderer instances.
* Update KatexRenderer.svelte
ResponseMessage compared the entire message object via JSON.stringify on every reactive tick to detect changes. During streaming, content changes on every token, making the two O(content_length) JSON.stringify calls always return different results — pure wasted work. Add a fast O(1) comparison on content and done fields first. When either differs (the common streaming case), skip straight to cloning. Only fall through to the expensive JSON.stringify comparison for infrequent changes like sources, annotations, or status updates.