perf(GradientBlinds): defer getBoundingClientRect to rAF on resize

Optimizes `GradientBlinds` layout performance by using `ResizeObserverEntry.contentRect` for immediate renderer resizing and deferring the expensive `getBoundingClientRect()` call (required for mouse interaction mapping) to the next animation frame. This prevents synchronous layout thrashing inside the `ResizeObserver` callback.

- Updates `resize` to accept `ResizeObserverEntry[]`
- Uses `contentRect` for `renderer.setSize`
- Defers `rectRef` update to `requestAnimationFrame`

Co-authored-by: ragusa-it <196988693+ragusa-it@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot]
2026-02-03 01:47:43 +00:00
parent 2587b9dd29
commit 7ecfd04f35

View File

@@ -280,18 +280,36 @@ void main() {
const mesh = new Mesh(gl, { geometry, program });
meshRef.current = mesh;
const resize = () => {
const rect = container.getBoundingClientRect();
rectRef.current = rect;
const resize = (entries?: ResizeObserverEntry[]) => {
let width, height;
if (entries && entries.length > 0) {
const entry = entries[0];
width = entry.contentRect.width;
height = entry.contentRect.height;
// Optimization: Defer calling getBoundingClientRect (which forces layout)
// to the next frame, since ResizeObserver runs after layout but before paint.
requestAnimationFrame(() => {
if (rendererRef.current) {
rectRef.current = container.getBoundingClientRect();
}
});
} else {
const rect = container.getBoundingClientRect();
rectRef.current = rect;
width = rect.width;
height = rect.height;
}
if (typeof window !== 'undefined') {
isMobileRef.current = window.innerWidth <= 768;
scrollPosRef.current = { x: window.scrollX, y: window.scrollY };
}
renderer.setSize(rect.width, rect.height);
renderer.setSize(width, height);
uniforms.iResolution.value = [gl.drawingBufferWidth, gl.drawingBufferHeight, 1];
if (blindMinWidth && blindMinWidth > 0) {
const maxByMinWidth = Math.max(1, Math.floor(rect.width / blindMinWidth));
const maxByMinWidth = Math.max(1, Math.floor(width / blindMinWidth));
const effective = blindCount ? Math.min(blindCount, maxByMinWidth) : maxByMinWidth;
uniforms.uBlindCount.value = Math.max(1, effective);