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 });
|
const mesh = new Mesh(gl, { geometry, program });
|
||||||
meshRef.current = mesh;
|
meshRef.current = mesh;
|
||||||
|
|
||||||
const resize = () => {
|
const resize = (entries?: ResizeObserverEntry[]) => {
|
||||||
const rect = container.getBoundingClientRect();
|
let width, height;
|
||||||
rectRef.current = rect;
|
|
||||||
|
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') {
|
if (typeof window !== 'undefined') {
|
||||||
isMobileRef.current = window.innerWidth <= 768;
|
isMobileRef.current = window.innerWidth <= 768;
|
||||||
scrollPosRef.current = { x: window.scrollX, y: window.scrollY };
|
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];
|
uniforms.iResolution.value = [gl.drawingBufferWidth, gl.drawingBufferHeight, 1];
|
||||||
|
|
||||||
if (blindMinWidth && blindMinWidth > 0) {
|
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;
|
const effective = blindCount ? Math.min(blindCount, maxByMinWidth) : maxByMinWidth;
|
||||||
uniforms.uBlindCount.value = Math.max(1, effective);
|
uniforms.uBlindCount.value = Math.max(1, effective);
|
||||||
|
|||||||
Reference in New Issue
Block a user