Description
src/shared/MotionLayer.jsx registers scroll, mousemove, and resize listeners on window inside useEffect hooks. None of these hooks return a cleanup function. During React hot-module reload (HMR) in development, or when the component unmounts and remounts, duplicate listeners accumulate on the window object, causing the same callback to fire multiple times per event and gradually degrading performance.
Steps to Reproduce
- Open the app in development mode with React DevTools installed.
- Navigate between pages several times to trigger component unmount/remount cycles.
- In DevTools Performance tab, record a scroll event and observe the event handler count multiplies with each mount cycle.
Root Cause
useEffect(() => { window.addEventListener("scroll", handler); }, []) without a corresponding return () => window.removeEventListener("scroll", handler).
Impact
Memory leak and compounding CPU cost on every scroll/mouse event. On low-power devices this becomes noticeable as stuttering after a few page navigations.
Proposed Fix
useEffect(() => {
const handleScroll = () => { /* ... */ };
window.addEventListener("scroll", handleScroll, { passive: true });
return () => window.removeEventListener("scroll", handleScroll);
}, []);
Apply this pattern to every addEventListener call in MotionLayer.jsx.
Description
src/shared/MotionLayer.jsxregistersscroll,mousemove, andresizelisteners onwindowinsideuseEffecthooks. None of these hooks return a cleanup function. During React hot-module reload (HMR) in development, or when the component unmounts and remounts, duplicate listeners accumulate on the window object, causing the same callback to fire multiple times per event and gradually degrading performance.Steps to Reproduce
Root Cause
useEffect(() => { window.addEventListener("scroll", handler); }, [])without a correspondingreturn () => window.removeEventListener("scroll", handler).Impact
Memory leak and compounding CPU cost on every scroll/mouse event. On low-power devices this becomes noticeable as stuttering after a few page navigations.
Proposed Fix
Apply this pattern to every
addEventListenercall inMotionLayer.jsx.