Skip to content

Commit bc9dbf2

Browse files
committed
fix(webview): resolve memory leak in ChatView by stabilizing callback props
- Stabilize handleSendMessage using clineAskRef to prevent frequent re-creation - Stabilize toggleRowExpansion by extracting handleSetExpandedRow and managing dependencies - Re-integrate scrolling logic into useEffect hook to avoid destabilizing callbacks - Add everVisibleMessagesTsRef to reduce unnecessary ChatRow remounts by Virtuoso - Update onToggleExpand signature to accept timestamp parameter for better stability - Remove diagnostic console.log statements used for debugging callback changes These changes address detached DOM elements memory leak caused by frequent callback re-creation triggering unnecessary component re-renders and preventing proper garbage collection of chat message DOM nodes.
1 parent 1e5bf74 commit bc9dbf2

File tree

4 files changed

+156
-105
lines changed

4 files changed

+156
-105
lines changed

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"i18next": "^24.2.2",
4848
"i18next-http-backend": "^3.0.2",
4949
"knuth-shuffle-seeded": "^1.0.6",
50+
"lru-cache": "^11.1.0",
5051
"lucide-react": "^0.510.0",
5152
"mermaid": "^11.4.1",
5253
"posthog-js": "^1.227.2",
@@ -70,8 +71,8 @@
7071
"tailwindcss": "^4.0.0",
7172
"tailwindcss-animate": "^1.0.7",
7273
"unist-util-visit": "^5.0.0",
73-
"vscode-material-icons": "^0.1.1",
7474
"use-sound": "^5.0.0",
75+
"vscode-material-icons": "^0.1.1",
7576
"vscrui": "^0.2.2",
7677
"zod": "^3.24.2"
7778
},

webview-ui/src/components/chat/ChatRow.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ interface ChatRowProps {
4444
isExpanded: boolean
4545
isLast: boolean
4646
isStreaming: boolean
47-
onToggleExpand: () => void
47+
onToggleExpand: (ts: number) => void // Modified to accept timestamp
4848
onHeightChange: (isTaller: boolean) => void
4949
onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void
5050
}
@@ -302,7 +302,7 @@ export const ChatRowContent = ({
302302
progressStatus={message.progressStatus}
303303
isLoading={message.partial}
304304
isExpanded={isExpanded}
305-
onToggleExpand={onToggleExpand}
305+
onToggleExpand={() => onToggleExpand(message.ts)}
306306
/>
307307
</>
308308
)
@@ -328,7 +328,7 @@ export const ChatRowContent = ({
328328
progressStatus={message.progressStatus}
329329
isLoading={message.partial}
330330
isExpanded={isExpanded}
331-
onToggleExpand={onToggleExpand}
331+
onToggleExpand={() => onToggleExpand(message.ts)}
332332
/>
333333
</>
334334
)
@@ -350,7 +350,7 @@ export const ChatRowContent = ({
350350
progressStatus={message.progressStatus}
351351
isLoading={message.partial}
352352
isExpanded={isExpanded}
353-
onToggleExpand={onToggleExpand}
353+
onToggleExpand={() => onToggleExpand(message.ts)}
354354
/>
355355
</>
356356
)
@@ -389,7 +389,7 @@ export const ChatRowContent = ({
389389
language={getLanguageFromPath(tool.path || "") || "log"}
390390
isLoading={message.partial}
391391
isExpanded={isExpanded}
392-
onToggleExpand={onToggleExpand}
392+
onToggleExpand={() => onToggleExpand(message.ts)}
393393
/>
394394
</>
395395
)
@@ -435,7 +435,7 @@ export const ChatRowContent = ({
435435
language="markdown"
436436
isLoading={message.partial}
437437
isExpanded={isExpanded}
438-
onToggleExpand={onToggleExpand}
438+
onToggleExpand={() => onToggleExpand(message.ts)}
439439
/>
440440
</>
441441
)
@@ -455,7 +455,7 @@ export const ChatRowContent = ({
455455
code={tool.content}
456456
language="shell-session"
457457
isExpanded={isExpanded}
458-
onToggleExpand={onToggleExpand}
458+
onToggleExpand={() => onToggleExpand(message.ts)}
459459
/>
460460
</>
461461
)
@@ -475,7 +475,7 @@ export const ChatRowContent = ({
475475
code={tool.content}
476476
language="shellsession"
477477
isExpanded={isExpanded}
478-
onToggleExpand={onToggleExpand}
478+
onToggleExpand={() => onToggleExpand(message.ts)}
479479
/>
480480
</>
481481
)
@@ -495,7 +495,7 @@ export const ChatRowContent = ({
495495
code={tool.content}
496496
language="markdown"
497497
isExpanded={isExpanded}
498-
onToggleExpand={onToggleExpand}
498+
onToggleExpand={() => onToggleExpand(message.ts)}
499499
/>
500500
</>
501501
)
@@ -525,7 +525,7 @@ export const ChatRowContent = ({
525525
code={tool.content}
526526
language="shellsession"
527527
isExpanded={isExpanded}
528-
onToggleExpand={onToggleExpand}
528+
onToggleExpand={() => onToggleExpand(message.ts)}
529529
/>
530530
</>
531531
)
@@ -813,7 +813,7 @@ export const ChatRowContent = ({
813813
MozUserSelect: "none",
814814
msUserSelect: "none",
815815
}}
816-
onClick={onToggleExpand}>
816+
onClick={() => onToggleExpand(message.ts)}>
817817
<div style={{ display: "flex", alignItems: "center", gap: "10px", flexGrow: 1 }}>
818818
{icon}
819819
{title}
@@ -852,7 +852,7 @@ export const ChatRowContent = ({
852852
code={safeJsonParse<any>(message.text)?.request}
853853
language="markdown"
854854
isExpanded={true}
855-
onToggleExpand={onToggleExpand}
855+
onToggleExpand={() => onToggleExpand(message.ts)}
856856
/>
857857
</div>
858858
)}
@@ -898,7 +898,7 @@ export const ChatRowContent = ({
898898
language="diff"
899899
isFeedback={true}
900900
isExpanded={isExpanded}
901-
onToggleExpand={onToggleExpand}
901+
onToggleExpand={() => onToggleExpand(message.ts)}
902902
/>
903903
</div>
904904
)
@@ -945,7 +945,7 @@ export const ChatRowContent = ({
945945
code={message.text}
946946
language="json"
947947
isExpanded={true}
948-
onToggleExpand={onToggleExpand}
948+
onToggleExpand={() => onToggleExpand(message.ts)}
949949
/>
950950
</div>
951951
</>
@@ -1105,7 +1105,7 @@ export const ChatRowContent = ({
11051105
code={useMcpServer.arguments}
11061106
language="json"
11071107
isExpanded={true}
1108-
onToggleExpand={onToggleExpand}
1108+
onToggleExpand={() => onToggleExpand(message.ts)}
11091109
/>
11101110
</div>
11111111
)}

0 commit comments

Comments
 (0)