perf: optimized gradientblinds
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user