perf: optimized gradientblinds

This commit is contained in:
Melvin Ragusa
2026-01-24 11:33:46 +01:00
parent e6df2d25be
commit 6b17b8b007
2 changed files with 55 additions and 12 deletions

View File

@@ -28,6 +28,7 @@ vi.mock('ogl', () => {
Triangle: class {
remove() { }
},
};
});
@@ -41,6 +42,8 @@ globalThis.ResizeObserver = class ResizeObserver {
describe('GradientBlinds', () => {
let rafSpy: any;
let cancelRafSpy: any;
let addEventListenerSpy: any;
let removeEventListenerSpy: any;
let ioCallback: (entries: IntersectionObserverEntry[]) => void;
let observeSpy: any;
let disconnectSpy: any;
@@ -51,6 +54,8 @@ describe('GradientBlinds', () => {
});
cancelRafSpy = vi.spyOn(window, 'cancelAnimationFrame').mockImplementation((_id: number) => {
});
addEventListenerSpy = vi.spyOn(window, 'addEventListener');
removeEventListenerSpy = vi.spyOn(window, 'removeEventListener');
// Mock IntersectionObserver
observeSpy = vi.fn();
@@ -133,6 +138,44 @@ describe('GradientBlinds', () => {
expect(disconnectSpy).toHaveBeenCalled();
});
it('toggles pointer event listener based on visibility', () => {
const { unmount } = render(<GradientBlinds />);
// Should not listen initially (not visible)
// Initially not called
expect(addEventListenerSpy).not.toHaveBeenCalledWith('pointermove', expect.any(Function));
// Simulate on-screen
act(() => {
if (ioCallback) {
ioCallback([{ isIntersecting: true } as IntersectionObserverEntry]);
}
});
expect(addEventListenerSpy).toHaveBeenCalledWith('pointermove', expect.any(Function));
// Reset
addEventListenerSpy.mockClear();
removeEventListenerSpy.mockClear();
// Simulate off-screen
act(() => {
if (ioCallback) {
ioCallback([{ isIntersecting: false } as IntersectionObserverEntry]);
}
});
expect(removeEventListenerSpy).toHaveBeenCalledWith('pointermove', expect.any(Function));
// Simulate on-screen again
act(() => {
if (ioCallback) {
ioCallback([{ isIntersecting: true } as IntersectionObserverEntry]);
}
});
expect(addEventListenerSpy).toHaveBeenCalledWith('pointermove', expect.any(Function));
unmount();
expect(removeEventListenerSpy).toHaveBeenCalledWith('pointermove', expect.any(Function));
});
it('minimizes getBoundingClientRect calls during pointer move', () => {
const { unmount } = render(<GradientBlinds />);
@@ -155,8 +198,7 @@ describe('GradientBlinds', () => {
window.dispatchEvent(event);
});
// EXPECTATION: It should NOT be called.
// This will fail currently.
// EXPECTATION: It should NOT be called because the listener shouldn't be attached (not visible)
expect(spy).not.toHaveBeenCalled();
unmount();

View File

@@ -330,7 +330,6 @@ void main() {
uniforms.iMouse.value = [x, y];
}
};
window.addEventListener('pointermove', onPointerMove);
const loop = (t: number) => {
rafRef.current = requestAnimationFrame(loop);
@@ -364,11 +363,13 @@ void main() {
lastTimeRef.current = 0;
rafRef.current = requestAnimationFrame(loop);
}
window.addEventListener('pointermove', onPointerMove);
} else {
if (rafRef.current) {
cancelAnimationFrame(rafRef.current);
rafRef.current = null;
}
window.removeEventListener('pointermove', onPointerMove);
}
});
observer.observe(container);