Optimize GradientBlinds with IntersectionObserver #10

Merged
google-labs-jules[bot] merged 1 commits from optimize-gradient-blinds-intersection-observer-8465585914404469487 into main 2026-01-23 09:55:48 +00:00
2 changed files with 19 additions and 4 deletions
Showing only changes of commit fe6e07fe92 - Show all commits

View File

@@ -66,8 +66,17 @@ describe('GradientBlinds', () => {
vi.clearAllMocks(); vi.clearAllMocks();
}); });
it('starts animation loop on mount', () => { it('does not start animation loop on mount until visible', () => {
const { unmount } = render(<GradientBlinds />); const { unmount } = render(<GradientBlinds />);
expect(rafSpy).not.toHaveBeenCalled();
// Simulate on-screen
act(() => {
if (ioCallback) {
ioCallback([{ isIntersecting: true } as IntersectionObserverEntry]);
}
});
expect(rafSpy).toHaveBeenCalled(); expect(rafSpy).toHaveBeenCalled();
unmount(); unmount();
expect(cancelRafSpy).toHaveBeenCalled(); expect(cancelRafSpy).toHaveBeenCalled();
@@ -76,7 +85,15 @@ describe('GradientBlinds', () => {
it('pauses animation loop when off-screen and resumes when on-screen', () => { it('pauses animation loop when off-screen and resumes when on-screen', () => {
const { unmount } = render(<GradientBlinds />); const { unmount } = render(<GradientBlinds />);
// Initial start // Should not start initially
expect(rafSpy).not.toHaveBeenCalled();
// Simulate on-screen (start)
act(() => {
if (ioCallback) {
ioCallback([{ isIntersecting: true } as IntersectionObserverEntry]);
}
});
expect(rafSpy).toHaveBeenCalledTimes(1); expect(rafSpy).toHaveBeenCalledTimes(1);
// Reset spies to check for subsequent calls // Reset spies to check for subsequent calls

View File

@@ -349,8 +349,6 @@ void main() {
}); });
observer.observe(container); observer.observe(container);
rafRef.current = requestAnimationFrame(loop);
return () => { return () => {
if (rafRef.current) cancelAnimationFrame(rafRef.current); if (rafRef.current) cancelAnimationFrame(rafRef.current);
canvas.removeEventListener('pointermove', onPointerMove); canvas.removeEventListener('pointermove', onPointerMove);