From 5efcd718b2d0378e6d1515b7c7b2e7c2847ea5f0 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sun, 31 May 2026 06:21:38 -0700 Subject: [PATCH] perf: move browser grab timer cleanup to root ref (#4158) --- .../components/browser-pane/BrowserPane.tsx | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/renderer/src/components/browser-pane/BrowserPane.tsx b/src/renderer/src/components/browser-pane/BrowserPane.tsx index c8b79edfbb0..c4f0aaea9c9 100644 --- a/src/renderer/src/components/browser-pane/BrowserPane.tsx +++ b/src/renderer/src/components/browser-pane/BrowserPane.tsx @@ -2516,6 +2516,18 @@ function BrowserPagePane({ }): React.JSX.Element { const isPaintable = isActive || isAutomationVisible const containerRef = useRef(null) + const grabToastTimerRef = useRef>(undefined) + const annotationCopyTimerRef = useRef>(undefined) + const setContainerRef = useCallback((node: HTMLDivElement | null): void => { + containerRef.current = node + if (node !== null) { + return + } + // Why: feedback timers are scoped to this pane owner and must not fire + // after the DOM owner is detached. + clearTimeout(grabToastTimerRef.current) + clearTimeout(annotationCopyTimerRef.current) + }, []) const addressBarInputRef = useRef(null) const webviewRef = useRef(null) const browserTabIdRef = useRef(browserTab.id) @@ -2653,17 +2665,6 @@ function BrowserPagePane({ below: boolean payload: BrowserGrabPayload | null } | null>(null) - const grabToastTimerRef = useRef>(undefined) - const annotationCopyTimerRef = useRef>(undefined) - // Why: clear the toast auto-dismiss timer on unmount so it cannot fire - // after the component is destroyed (prevents setState-on-unmounted warnings - // and stale rearm calls). - useEffect(() => { - return () => { - clearTimeout(grabToastTimerRef.current) - clearTimeout(annotationCopyTimerRef.current) - } - }, []) const grabRef = useRef(grab) grabRef.current = grab @@ -4726,7 +4727,7 @@ function BrowserPagePane({ ) : null}