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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user