Conversation
Co-authored-by: Apurv-15 <95355502+Apurv-15@users.noreply.github.com> Agent-Logs-Url: https://github.com/GDGVITM/Spectrum-web-2026/sessions/29040fd8-30cf-4d5f-aa10-012ec8a99884
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR addresses mobile/iPad “page not responding” freezes by reducing animation/GPU load and fixing a Lenis requestAnimationFrame lifecycle leak in the landing page.
Changes:
- Cancel Lenis RAF loop on unmount and disable Lenis entirely on touch devices.
- Reduce canvas DPR on small screens and lower particle counts/animations on touch devices.
- Add a shared
isTouchDevice()utility used across pages.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/debounce.ts | Adds isTouchDevice() shared helper alongside existing debounce utility. |
| src/pages/landingRevamp/LandingRevamp.tsx | Caps canvas DPR on small screens; cancels Lenis RAF on cleanup; disables Lenis on touch. |
| src/pages/invasion/Invasion.tsx | Reduces particle counts and disables ember flicker animation on mobile/touch. |
| src/pages/events/Events.tsx | Reduces sakura/lantern DOM particle counts on mobile/touch. |
| package-lock.json | Updates dependency metadata flags for @types/react and csstype. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const isTouchDevice = (): boolean => | ||
| window.matchMedia("(hover: none) and (pointer: coarse)").matches; |
There was a problem hiding this comment.
isTouchDevice() assumes window.matchMedia is always available. This will throw in non-browser contexts (SSR, some test runners) or if matchMedia is missing. Add a typeof window !== "undefined" / typeof window.matchMedia === "function" guard and a safe fallback (e.g., navigator.maxTouchPoints > 0) so callers can use it without crashing.
| export const isTouchDevice = (): boolean => | |
| window.matchMedia("(hover: none) and (pointer: coarse)").matches; | |
| export const isTouchDevice = (): boolean => { | |
| // Guard against non-browser environments (SSR, some test runners) | |
| if (typeof window === "undefined") { | |
| return false; | |
| } | |
| // Prefer navigator.maxTouchPoints when available | |
| if (typeof navigator !== "undefined" && typeof navigator.maxTouchPoints === "number") { | |
| if (navigator.maxTouchPoints > 0) { | |
| return true; | |
| } | |
| } | |
| // Fallback to matchMedia when supported | |
| if (typeof window.matchMedia === "function") { | |
| try { | |
| return window.matchMedia("(hover: none) and (pointer: coarse)").matches; | |
| } catch { | |
| // If matchMedia throws for any reason, fall through to default | |
| } | |
| } | |
| // Conservative default when we cannot reliably detect touch capability | |
| return false; | |
| }; |
| const isMobile = window.innerWidth < 768; | ||
| const dpr = isMobile ? 1 : Math.min(window.devicePixelRatio || 1, 2); | ||
| canvas.width = window.innerWidth * dpr; | ||
| canvas.height = window.innerHeight * dpr; |
There was a problem hiding this comment.
The DPR cap uses window.innerWidth < 768 to decide “mobile”, which excludes many iPads/tablets (often >= 768px wide). If the goal is to reduce canvas GPU memory on iPad too, consider basing the DPR cap on isTouchDevice() (or a max pixel budget) instead of only viewport width so tablets don’t still allocate at DPR 2.
Website was auto-loading then freezing ("page not responding") on mobile/iPad due to three compounding issues: an infinite RAF loop that was never cancelled on unmount, oversized canvas buffers, and too many simultaneously animated DOM nodes.
Changes
🔴 Lenis RAF loop never cancelled (critical memory leak)
cancelAnimationFramewas never called on unmount — every landing page visit stacked a new infinite looplenisRafIdand cancelling in cleanupisTouchDevice()) — native scroll is sufficient and Lenis adds measurable CPU overhead on mobile🟠 Canvas DPR capped at 1 on mobile
min(DPR, 2)— still doubles canvas resolution on phones, wasting GPU memory1whenwindow.innerWidth < 768🟡 Particle counts reduced on mobile
repeat: -1ember flicker disabled on mobileShared utility
isTouchDevice()intosrc/utils/debounce.ts— consistent detection across all three pages