🚀 Fix: Global Scroll Performance Optimization & FAQ Page UI Enhancement (#318)#321
Conversation
|
@Akash972004 is attempting to deploy a commit to the santanu-atta03's projects Team on Vercel. A member of the Team first needs to authorize it. |
Thanks for creating a PR for your Issue!
|
There was a problem hiding this comment.
Pull request overview
This PR aims to eliminate site-wide scroll lag by introducing Lenis smooth scrolling at the app level, and significantly modernizes the FAQ page with animated UI/accordion interactions and enhanced styling.
Changes:
- Add a global Lenis initialization (RAF-driven) in
App.jsxfor smooth scrolling across routes. - Redesign
FAQ.jsxwith Framer Motion animations, category icons, hover/active effects, and a new CTA section. - Add Lenis-related global CSS utilities and new keyframe animations in
index.css(plus lockfile updates).
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
Frontend/src/App.jsx |
Introduces global Lenis smooth-scroll initialization via useEffect + RAF loop. |
Frontend/src/pages/FAQ.jsx |
Full FAQ UI overhaul with Framer Motion animations, icon categories, and CTA section. |
Frontend/src/index.css |
Adds Lenis CSS helpers and additional animations/utilities. |
Frontend/package-lock.json |
Lockfile updates reflecting dependency graph changes. |
Files not reviewed (1)
- Frontend/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)
Frontend/src/pages/FAQ.jsx:108
handleScrollcallssetScrollYon every scroll event, forcing React re-renders at scroll frequency (which can reintroduce scroll jank on this animation-heavy page). Consider throttling viarequestAnimationFrame, using a passive listener with a rAF throttle, or using Framer Motion’suseScroll/motion values so the navbar style updates without re-rendering the whole component.
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| /* Smooth scrolling setup */ | ||
| html { | ||
| scroll-behavior: smooth; |
There was a problem hiding this comment.
With Lenis controlling scrolling, setting html { scroll-behavior: smooth; } can cause double-smoothing/odd behavior for anchor links and programmatic scrolls (and App.jsx also injects an html { scroll-behavior: smooth; } rule). Consider leaving the default as auto and relying on Lenis (or applying smooth behavior only when Lenis is not active).
| scroll-behavior: smooth; | |
| scroll-behavior: auto; |
| import ScrollToTopOnRouteChange from "./components/shared/ScrollToTopOnRouteChange"; | ||
| import Navbar from "./components/Navbar"; | ||
| import { useEffect } from "react"; | ||
| import Lenis from "@studio-freight/lenis"; |
There was a problem hiding this comment.
@studio-freight/lenis is marked deprecated in the lockfile; it has been renamed to lenis. Consider migrating the dependency/import to lenis to avoid relying on a deprecated package and to stay aligned with upstream docs/support.
| import Lenis from "@studio-freight/lenis"; | |
| import Lenis from "lenis"; |
| // Initialize smooth scrolling with Lenis | ||
| useEffect(() => { | ||
| const lenis = new Lenis({ | ||
| duration: 1.2, | ||
| easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), |
There was a problem hiding this comment.
This introduces a global Lenis instance, but several pages already create their own Lenis + RAF loop (e.g. Landing/AboutUs/ContactUs/PricingPage). Multiple simultaneous instances can fight over scroll state and create multiple RAF loops. Consider centralizing Lenis in one place (App/context/hook) and removing per-page initializations, or guarding so only one instance exists.
| direction: "vertical", | ||
| gestureDirection: "vertical", | ||
| smooth: true, |
There was a problem hiding this comment.
The Lenis options here (e.g. direction, gestureDirection, smooth) don’t match the option keys used elsewhere in this repo for the same library (orientation, gestureOrientation, smoothWheel). If these keys are incorrect for the installed Lenis version they’ll be ignored, causing scrolling not to be configured as intended. Please align the option names with the working usage used in other pages.
| direction: "vertical", | |
| gestureDirection: "vertical", | |
| smooth: true, | |
| orientation: "vertical", | |
| gestureOrientation: "vertical", | |
| smoothWheel: true, |
| function raf(time) { | ||
| lenis.raf(time); | ||
| requestAnimationFrame(raf); | ||
| } | ||
|
|
||
| requestAnimationFrame(raf); | ||
|
|
||
| return () => { |
There was a problem hiding this comment.
The RAF loop isn’t cancellable. After unmount, requestAnimationFrame(raf) will keep running and may call lenis.raf after lenis.destroy(), causing leaks or errors. Store the RAF id (or use a running flag) and cancel/stop the loop in the cleanup.
| function raf(time) { | |
| lenis.raf(time); | |
| requestAnimationFrame(raf); | |
| } | |
| requestAnimationFrame(raf); | |
| return () => { | |
| let rafId; | |
| function raf(time) { | |
| lenis.raf(time); | |
| rafId = requestAnimationFrame(raf); | |
| } | |
| rafId = requestAnimationFrame(raf); | |
| return () => { | |
| if (rafId) { | |
| cancelAnimationFrame(rafId); | |
| } |
| import { | ||
| ChevronDown, | ||
| Sparkles, | ||
| HelpCircle, |
There was a problem hiding this comment.
HelpCircle is imported but never used. This will trigger lint/build warnings; please remove it or use it in the UI.
| HelpCircle, |
| /> | ||
| )} | ||
|
|
||
| <button |
There was a problem hiding this comment.
The accordion trigger button is missing common accessibility attributes. Consider adding type="button", aria-expanded={isActive}, and aria-controls pointing at the answer region (with a stable id) so screen readers can understand the expand/collapse state.
| <button | |
| <button | |
| type="button" | |
| aria-expanded={isActive} |
Overview
This PR resolves the global scroll lag issue by integrating the Lenis smooth scrolling library and completely redesigns the FAQ page with modern animations, improved UI aesthetics, and enhanced interaction feedback.
The update significantly improves performance, smoothness, and visual appeal across the website.
✨ Smooth Scrolling Implementation
Integrated Lenis smooth scrolling library in App.jsx
Configured optimized easing and duration settings
Implemented requestAnimationFrame (RAF) loop for high-performance scrolling
Added necessary Lenis CSS utilities for consistent scroll behavior
Improved animation smoothness across pages
Reduced scroll stuttering and performance bottlenecks
✅ Result: Butter-smooth scrolling experience across the entire website.
🎯 FAQ Page Redesign & UI Enhancement
🎨 Visual & Layout Improvements
Fully redesigned FAQ layout with modern UI
Added animated gradient background with three floating orbs
Implemented glassmorphism effects using backdrop blur
Improved typography, spacing, and visual hierarchy
Enhanced CTA section with animated gradient and icons
Upgraded navbar with animated logo and gradient buttons
🎬 Animation Enhancements
Integrated Framer Motion for smooth animations
Added staggered entry effects for FAQ items
Implemented smooth accordion expand/collapse with spring physics
Added hover glow effects and rotating icons
Introduced pulse-glow animation in CSS
Implemented category-based icon system (6 categories with unique colors)
✅ Result: A modern, engaging, and interactive FAQ experience.
🧪 Testing & Verification
Verified smooth scrolling behavior across all pages
Tested performance during rapid scroll interactions
Ensured animations run smoothly without frame drops
Confirmed FAQ accordion responsiveness on mobile, tablet, and desktop
Validated visual consistency across browsers
🎯 Impact
Eliminates global scroll lag
Improves perceived and actual performance
Enhances UI modernity and user engagement
Provides smoother animations and better interaction feedback
Elevates overall website experience
Closes #318