From 49006ee5895306cc3343aab6c98068c77a632fa4 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 2 May 2026 22:33:29 +0500 Subject: [PATCH] perf: memo CodeBlockViewer, DiffViewer, CompactBoundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are the most expensive render components (syntax highlighting, diff computation) — memoizing them prevents re-renders when parent tool items toggle expand/collapse or parent chat group updates. --- src/renderer/components/chat/CompactBoundary.tsx | 8 ++++---- src/renderer/components/chat/viewers/CodeBlockViewer.tsx | 8 ++++---- src/renderer/components/chat/viewers/DiffViewer.tsx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/renderer/components/chat/CompactBoundary.tsx b/src/renderer/components/chat/CompactBoundary.tsx index d23dc752..88f44216 100644 --- a/src/renderer/components/chat/CompactBoundary.tsx +++ b/src/renderer/components/chat/CompactBoundary.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { memo, useState } from 'react'; import ReactMarkdown from 'react-markdown'; import { @@ -28,9 +28,9 @@ interface CompactBoundaryProps { * CompactBoundary displays a horizontal divider indicating where * the conversation was compacted. Click to expand the compacted summary. */ -export const CompactBoundary = ({ +export const CompactBoundary = memo(function CompactBoundary({ compactGroup, -}: Readonly): React.JSX.Element => { +}: Readonly): React.JSX.Element { const { timestamp, message } = compactGroup; const [isExpanded, setIsExpanded] = useState(false); @@ -166,4 +166,4 @@ export const CompactBoundary = ({ )} ); -}; +}); diff --git a/src/renderer/components/chat/viewers/CodeBlockViewer.tsx b/src/renderer/components/chat/viewers/CodeBlockViewer.tsx index d694f3f1..9edb7a64 100644 --- a/src/renderer/components/chat/viewers/CodeBlockViewer.tsx +++ b/src/renderer/components/chat/viewers/CodeBlockViewer.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from 'react'; +import React, { memo, useMemo, useState } from 'react'; import { getBaseName } from '@renderer/utils/pathUtils'; import { createLogger } from '@shared/utils/logger'; @@ -117,14 +117,14 @@ function inferLanguage(fileName: string): string { // Component // ============================================================================= -export const CodeBlockViewer: React.FC = ({ +export const CodeBlockViewer = memo(function CodeBlockViewer({ fileName, content, language, startLine = 1, endLine, maxHeight = 'max-h-96', -}): React.JSX.Element => { +}: CodeBlockViewerProps): React.JSX.Element { const [isCopied, setIsCopied] = useState(false); // Infer language from file extension if not provided @@ -241,4 +241,4 @@ export const CodeBlockViewer: React.FC = ({ ); -}; +}); diff --git a/src/renderer/components/chat/viewers/DiffViewer.tsx b/src/renderer/components/chat/viewers/DiffViewer.tsx index 3400051d..efb74cd6 100644 --- a/src/renderer/components/chat/viewers/DiffViewer.tsx +++ b/src/renderer/components/chat/viewers/DiffViewer.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { memo, useMemo } from 'react'; import { CODE_BG, @@ -349,14 +349,14 @@ const DiffLineRow: React.FC = ({ line, highlightedHtml }): Rea // Main Component // ============================================================================= -export const DiffViewer: React.FC = ({ +export const DiffViewer = memo(function DiffViewer({ fileName, oldString, newString, maxHeight = 'max-h-96', tokenCount, syntaxHighlight = false, -}): React.JSX.Element => { +}: DiffViewerProps): React.JSX.Element { // Compute diff const oldLines = oldString.split(/\r?\n/); const newLines = newString.split(/\r?\n/); @@ -456,4 +456,4 @@ export const DiffViewer: React.FC = ({ ); -}; +});