From 351af77bd2f8c7d4b8632b4d61fd91b280c46951 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 02:19:28 +0000 Subject: [PATCH] perf(GradientBlinds): optimize GC and layout thrashing - Replace `pointerPosRef` and `mouseTargetRef` with mutable refs to prevent per-frame object allocation. - Remove `getBoundingClientRect` from `requestAnimationFrame` loop to prevent synchronous layout thrashing. - Fix `uniforms.iMouse.value` update logic to mutate array in-place. Co-authored-by: ragusa-it <196988693+ragusa-it@users.noreply.github.com> --- src/components/effects/GradientBlinds.tsx | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/components/effects/GradientBlinds.tsx b/src/components/effects/GradientBlinds.tsx index 9f3b787..3f7aa76 100644 --- a/src/components/effects/GradientBlinds.tsx +++ b/src/components/effects/GradientBlinds.tsx @@ -65,7 +65,7 @@ const GradientBlinds: React.FC = ({ const rendererRef = useRef(null); const mouseTargetRef = useRef<[number, number]>([0, 0]); // Optimization: store raw pointer position (viewport coords) to decouple event handling from calculation - const pointerPosRef = useRef<{ x: number; y: number } | null>(null); + const pointerPosRef = useRef<{ x: number; y: number; active: boolean }>({ x: 0, y: 0, active: false }); const isMobileRef = useRef(false); const lastTimeRef = useRef(0); const firstResizeRef = useRef(true); @@ -303,8 +303,10 @@ void main() { firstResizeRef.current = false; const cx = gl.drawingBufferWidth / 2; const cy = gl.drawingBufferHeight / 2; - uniforms.iMouse.value = [cx, cy]; - mouseTargetRef.current = [cx, cy]; + uniforms.iMouse.value[0] = cx; + uniforms.iMouse.value[1] = cy; + mouseTargetRef.current[0] = cx; + mouseTargetRef.current[1] = cy; } }; @@ -332,10 +334,13 @@ void main() { x = (e.clientX - rect.left) * scale; y = (rect.height - (e.clientY - rect.top)) * scale; } - mouseTargetRef.current = [x, y]; - pointerPosRef.current = null; // Ensure loop doesn't override + mouseTargetRef.current[0] = x; + mouseTargetRef.current[1] = y; + pointerPosRef.current.active = false; // Ensure loop doesn't override } else { - pointerPosRef.current = { x: e.clientX, y: e.clientY }; + pointerPosRef.current.x = e.clientX; + pointerPosRef.current.y = e.clientY; + pointerPosRef.current.active = true; } }; @@ -344,24 +349,18 @@ void main() { uniforms.iTime.value = t * 0.001; // Update target based on pointer position and scroll offset - if (pointerPosRef.current) { + if (pointerPosRef.current.active && rectRef.current) { const scale = (renderer as unknown as { dpr?: number }).dpr || 1; - let x, y; - if (rectRef.current) { - const dx = window.scrollX - scrollPosRef.current.x; - const dy = window.scrollY - scrollPosRef.current.y; - const rectLeft = rectRef.current.left - dx; - const rectTop = rectRef.current.top - dy; - x = (pointerPosRef.current.x - rectLeft) * scale; - y = (rectRef.current.height - (pointerPosRef.current.y - rectTop)) * scale; - } else { - // Fallback if rectRef missing - const rect = canvas.getBoundingClientRect(); - x = (pointerPosRef.current.x - rect.left) * scale; - y = (rect.height - (pointerPosRef.current.y - rect.top)) * scale; - } - mouseTargetRef.current = [x, y]; + const dx = window.scrollX - scrollPosRef.current.x; + const dy = window.scrollY - scrollPosRef.current.y; + const rectLeft = rectRef.current.left - dx; + const rectTop = rectRef.current.top - dy; + const x = (pointerPosRef.current.x - rectLeft) * scale; + const y = (rectRef.current.height - (pointerPosRef.current.y - rectTop)) * scale; + + mouseTargetRef.current[0] = x; + mouseTargetRef.current[1] = y; } if (mouseDampening > 0) { @@ -376,8 +375,9 @@ void main() { cur[0] += (target[0] - cur[0]) * factor; cur[1] += (target[1] - cur[1]) * factor; } else { - if (pointerPosRef.current || isMobileRef.current) { - uniforms.iMouse.value = mouseTargetRef.current; + if (pointerPosRef.current.active || isMobileRef.current) { + uniforms.iMouse.value[0] = mouseTargetRef.current[0]; + uniforms.iMouse.value[1] = mouseTargetRef.current[1]; } lastTimeRef.current = t; } -- 2.49.1