diff --git a/ui/desktop/src/components/MarkdownContent.tsx b/ui/desktop/src/components/MarkdownContent.tsx index 68d05d8849f6..5c4020fbda31 100644 --- a/ui/desktop/src/components/MarkdownContent.tsx +++ b/ui/desktop/src/components/MarkdownContent.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect, useRef, memo, useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import remarkBreaks from 'remark-breaks'; @@ -16,7 +16,14 @@ interface MarkdownContentProps { className?: string; } -const CodeBlock = ({ language, children }: { language: string; children: string }) => { +// Memoized CodeBlock component to prevent re-rendering when props haven't changed +const CodeBlock = memo(function CodeBlock({ + language, + children, +}: { + language: string; + children: string; +}) { const [copied, setCopied] = useState(false); const timeoutRef = useRef(null); @@ -43,6 +50,44 @@ const CodeBlock = ({ language, children }: { language: string; children: string }; }, []); + // Memoize the SyntaxHighlighter component to prevent re-rendering + // Only re-render if language or children change + const memoizedSyntaxHighlighter = useMemo(() => { + // For very large code blocks, consider truncating or lazy loading + const isLargeCodeBlock = children.length > 10000; // 10KB threshold + + if (isLargeCodeBlock) { + console.log(`Large code block detected (${children.length} chars), consider optimization`); + } + + return ( + + {children} + + ); + }, [language, children]); + return (
-
- - {children} - -
+
{memoizedSyntaxHighlighter}
); -}; - -const MarkdownCode = React.forwardRef(function MarkdownCode( - { inline, className, children, ...props }: CodeProps, - ref: React.Ref -) { - const match = /language-(\w+)/.exec(className || ''); - return !inline && match ? ( - {String(children).replace(/\n$/, '')} - ) : ( - - {children} - - ); }); -export default function MarkdownContent({ content, className = '' }: MarkdownContentProps) { +const MarkdownCode = memo( + React.forwardRef(function MarkdownCode( + { inline, className, children, ...props }: CodeProps, + ref: React.Ref + ) { + const match = /language-(\w+)/.exec(className || ''); + return !inline && match ? ( + {String(children).replace(/\n$/, '')} + ) : ( + + {children} + + ); + }) +); + +const MarkdownContent = memo(function MarkdownContent({ + content, + className = '', +}: MarkdownContentProps) { const [processedContent, setProcessedContent] = useState(content); useEffect(() => { @@ -137,4 +166,6 @@ export default function MarkdownContent({ content, className = '' }: MarkdownCon ); -} +}); + +export default MarkdownContent;