feat(MarkdownRenderer): Add blocks memoization and parsing incomplete chunks #84
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces performance optimizations for markdown rendering by implementing block-level memoization and adds support for parsing incomplete markdown chunks during streaming.
Changes
Performance Improvements
MarkdownRendereris now wrapped withReact.memowith custom comparison logic to prevent unnecessary re-renders when props haven't changedNew Features
remendlibrary, which automatically closes unclosed markdown tags and structuresshouldParseIncompleteMarkdown: Added toMarkdownRenderer,AssistantMessage,UserMessage,MessageList, andChatContainercomponents to enable incomplete markdown parsingNew Utilities and Hooks
useMarkdownTransformhook: Handles markdown transformation with block-level cachinguseRemendhook: Wraps theremendlibrary for closing incomplete markdown structuresparse-blocks.tsutility: Parses markdown content into individual blocks using themarkedlexer, handling HTML blocks and footnotes correctlyDependencies
marked(^17.0.1) - for markdown lexing and block parsingremend(^1.0.1) - for closing incomplete markdown structuresTechnical Details
The implementation splits markdown content into blocks using the
markedlexer. Each block is cached separately, so when new content is appended (e.g., during streaming), only new blocks are transformed while existing blocks are retrieved from cache. This significantly improves performance for long messages and streaming scenarios.The block parsing logic:
Screen.Recording.2025-12-24.at.17.54.49.mov