Просмотр исходного кода

perf: optimize code block rendering performance (#3135)

feat: optimize code block rendering performance

Memoize CodeBlock components to prevent unnecessary re-renders:
- Add MemoizedCodeContent for syntax highlighted HTML
- Add MemoizedStyledPre for container element
- Properly type all component props
- Reduce React reconciliation work for complex code blocks

Signed-off-by: Eric Wheeler <[email protected]>
Co-authored-by: Eric Wheeler <[email protected]>
KJ7LNW 8 месяцев назад
Родитель
Сommit
bd3a42ed23
1 измененных файлов с 42 добавлено и 8 удалено
  1. 42 8
      webview-ui/src/components/common/CodeBlock.tsx

+ 42 - 8
webview-ui/src/components/common/CodeBlock.tsx

@@ -604,16 +604,15 @@ const CodeBlock = memo(
 
 		return (
 			<CodeBlockContainer ref={codeBlockRef}>
-				<StyledPre
-					ref={preRef}
+				<MemoizedStyledPre
+					preRef={preRef}
 					preStyle={preStyle}
-					wordwrap={wordWrap ? "true" : "false"}
-					windowshade={windowShade ? "true" : "false"}
+					wordWrap={wordWrap}
+					windowShade={windowShade}
 					collapsedHeight={collapsedHeight}
-					onMouseDown={() => updateCodeBlockButtonPosition(true)}
-					onMouseUp={() => updateCodeBlockButtonPosition(false)}>
-					<div dangerouslySetInnerHTML={{ __html: highlightedCode }} />
-				</StyledPre>
+					highlightedCode={highlightedCode}
+					updateCodeBlockButtonPosition={updateCodeBlockButtonPosition}
+				/>
 				{!isSelecting && (
 					<CodeBlockButtonWrapper
 						ref={copyButtonWrapperRef}
@@ -718,4 +717,39 @@ const CodeBlock = memo(
 	},
 )
 
+// Memoized content component to prevent unnecessary re-renders of highlighted code
+const MemoizedCodeContent = memo(({ html }: { html: string }) => <div dangerouslySetInnerHTML={{ __html: html }} />)
+
+// Memoized StyledPre component
+const MemoizedStyledPre = memo(
+	({
+		preRef,
+		preStyle,
+		wordWrap,
+		windowShade,
+		collapsedHeight,
+		highlightedCode,
+		updateCodeBlockButtonPosition,
+	}: {
+		preRef: React.RefObject<HTMLDivElement>
+		preStyle?: React.CSSProperties
+		wordWrap: boolean
+		windowShade: boolean
+		collapsedHeight?: number
+		highlightedCode: string
+		updateCodeBlockButtonPosition: (forceHide?: boolean) => void
+	}) => (
+		<StyledPre
+			ref={preRef}
+			preStyle={preStyle}
+			wordwrap={wordWrap ? "true" : "false"}
+			windowshade={windowShade ? "true" : "false"}
+			collapsedHeight={collapsedHeight}
+			onMouseDown={() => updateCodeBlockButtonPosition(true)}
+			onMouseUp={() => updateCodeBlockButtonPosition(false)}>
+			<MemoizedCodeContent html={highlightedCode} />
+		</StyledPre>
+	),
+)
+
 export default CodeBlock