Skip to content

Conversation

@vLuckyyy
Copy link
Member

Major performance optimizations to achieve smooth 120Hz rendering:

CRITICAL fixes:

  • Throttle Lenis RAF loop to 120Hz (8.33ms frame time)
  • Reduce backdrop-blur usage (backdrop-blur-xl → backdrop-blur-sm)
  • Replace GPU-expensive backdrop-blur with higher opacity backgrounds

HIGH PRIORITY fixes:

  • Replace SVG pathLength animation with GPU-accelerated fade-in + scale
  • Refactor projects auto-scroll from RAF + scrollLeft to Framer Motion transforms
  • Remove filter: blur() animations from doc view items

MEDIUM PRIORITY fixes:

  • Optimize navbar scroll state to prevent unnecessary re-renders
  • Simplify search modal loading animation (infinite repeat → CSS pulse)
  • Add CSS containment utilities for animated containers

Performance improvements:

  • All animations now use GPU-accelerated properties (transform, opacity)
  • Eliminated layout thrashing and main thread blocking
  • Added contain: layout paint for animation isolation
  • Optimized for 120Hz displays while maintaining 60Hz compatibility

https://claude.ai/code/session_68DcS

Major performance optimizations to achieve smooth 120Hz rendering:

CRITICAL fixes:
- Throttle Lenis RAF loop to 120Hz (8.33ms frame time)
- Reduce backdrop-blur usage (backdrop-blur-xl → backdrop-blur-sm)
- Replace GPU-expensive backdrop-blur with higher opacity backgrounds

HIGH PRIORITY fixes:
- Replace SVG pathLength animation with GPU-accelerated fade-in + scale
- Refactor projects auto-scroll from RAF + scrollLeft to Framer Motion transforms
- Remove filter: blur() animations from doc view items

MEDIUM PRIORITY fixes:
- Optimize navbar scroll state to prevent unnecessary re-renders
- Simplify search modal loading animation (infinite repeat → CSS pulse)
- Add CSS containment utilities for animated containers

Performance improvements:
- All animations now use GPU-accelerated properties (transform, opacity)
- Eliminated layout thrashing and main thread blocking
- Added contain: layout paint for animation isolation
- Optimized for 120Hz displays while maintaining 60Hz compatibility

https://claude.ai/code/session_68DcS
@netlify
Copy link

netlify bot commented Jan 23, 2026

Deploy Preview for eternalcodeteam-website ready!

Name Link
🔨 Latest commit bf49ee3
🔍 Latest deploy log https://app.netlify.com/projects/eternalcodeteam-website/deploys/6973476b568b700008a41f67
😎 Deploy Preview https://deploy-preview-212--eternalcodeteam-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 36 (🔴 down 15 from production)
Accessibility: 94 (no change from production)
Best Practices: 92 (🔴 down 8 from production)
SEO: 100 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @vLuckyyy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a series of performance optimizations aimed at enhancing the smoothness and responsiveness of the application, particularly on high refresh rate displays. The changes include throttling requestAnimationFrame loops, reducing the use of costly CSS effects, and refactoring animations to leverage GPU acceleration. Additionally, CSS containment is employed to isolate rendering and prevent layout thrashing, resulting in a more efficient and fluid user experience.

Highlights

  • Performance Optimizations: This PR focuses on major performance improvements to achieve smoother rendering, especially on devices with 120Hz displays. Key optimizations include throttling the Lenis RAF loop, reducing backdrop blur usage, and replacing expensive SVG animations with GPU-accelerated alternatives.
  • CSS Containment: Added CSS containment utilities to isolate animated containers, preventing layout thrashing and improving rendering performance. New utility classes like .contain-layout and .contain-paint are introduced.
  • Animation Refactoring: Several animations have been refactored to use GPU-accelerated properties like transform and opacity, ensuring smoother transitions and reducing main thread blocking.
  • Search Modal Optimization: The search modal's loading animation has been simplified, replacing an infinite repeat animation with a CSS pulse effect for better performance.
  • Navbar Scroll State Optimization: The navbar's scroll state logic has been optimized to prevent unnecessary re-renders, improving overall responsiveness.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant performance optimizations across the application, aligning with the goal of achieving smooth 120Hz rendering. Key improvements include throttling the Lenis RAF loop, reducing the use of GPU-expensive backdrop-blur effects, replacing pathLength SVG animations with GPU-accelerated opacity and scale transforms, and refactoring the projects auto-scroll to use Framer Motion transforms instead of a custom requestAnimationFrame loop. Additionally, unnecessary re-renders in the navbar scroll state have been optimized, and filter: blur() animations have been removed from doc view items. New CSS utilities for containment and GPU acceleration have been added to support these changes. These modifications collectively contribute to a more performant and smoother user experience.

Comment on lines +35 to +47
// Throttle RAF to 120Hz (8.33ms per frame) for optimal performance
const targetFPS = 120;
const frameTime = 1000 / targetFPS;
let lastTime = 0;

function raf(time: number) {
// Skip frame if not enough time has passed
if (time - lastTime < frameTime) {
requestAnimationFrame(raf);
return;
}

lastTime = time;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The implementation of RAF throttling to 120Hz is a critical performance improvement. By ensuring that lenis.raf is only called when enough time has passed for a new frame at the target FPS, you prevent unnecessary work and align the animation loop with the display's refresh rate, leading to a much smoother experience, especially on high refresh rate monitors.

Comment on lines +15 to +22
initial={{ opacity: 0, scale: 0.98 }}
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
transition={{ duration: 2, ease: "easeInOut" }}
transition={{ duration: 1.5, ease: "easeOut" }}
viewport={{ once: true }}
whileInView={{ pathLength: 1 }}
whileInView={{ opacity: 1, scale: 1 }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Changing the SVG animation from pathLength to opacity and scale is a critical performance optimization. pathLength animations are often CPU-bound and can lead to janky rendering, whereas opacity and transform (scale) are typically GPU-accelerated properties. This refactoring ensures a much smoother and more efficient animation, directly addressing the PR's goal of GPU-accelerated animations.

Comment on lines +12 to 16
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
filter: "blur(0px)",
transition: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Removing filter: blur() from the itemVariants is a significant performance win. CSS filter properties, especially blur, are known to be very expensive for the GPU and can cause considerable jank during animations. This change directly addresses the PR's goal of eliminating such performance bottlenecks.

Comment on lines +112 to +128
<div className="no-scrollbar relative flex w-full overflow-hidden contain-layout">
<motion.div
animate={{
x: isHovered ? undefined : [`${-singleSetWidth}px`, "0px"],
}}
className="optimize-animation flex gap-6"
initial={{ x: 0 }}
transition={{
duration: 60,
ease: "linear",
repeat: Number.POSITIVE_INFINITY,
}}
>
{displayProjects.map((project, index) => (
<ProjectCard key={`${project.name}-${index}`} project={project} />
))}
</div>
</motion.div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Migrating the scrollable container to a motion.div with animate and transition properties, along with the optimize-animation and contain-layout classes, is a great refactoring. This leverages Framer Motion for GPU-accelerated x transforms, which is far more efficient for scrolling animations than manipulating scrollLeft. The contain properties further enhance performance by isolating the rendering of this animated element.

<motion.div
animate={{ opacity: 1 }}
className="fixed inset-0 z-[100] flex items-start justify-center overflow-y-auto overscroll-contain bg-black/70 p-0 pt-0 backdrop-blur-md md:p-4 md:pt-[10vh] md:backdrop-blur-sm"
className="fixed inset-0 z-[100] flex items-start justify-center overflow-y-auto overscroll-contain bg-black/80 p-0 pt-0 md:p-4 md:pt-[10vh]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The change from backdrop-blur-md to bg-black/80 is a good optimization, as backdrop-blur can be computationally intensive. This aligns with the PR's goal of replacing GPU-expensive backdrop-blur with higher opacity backgrounds for better performance.

>
{/* Modal Container with Enhanced Glassmorphism */}
<div className="flex h-full flex-col overflow-hidden rounded-none border-0 bg-white/98 shadow-2xl backdrop-blur-2xl md:h-auto md:rounded-2xl md:border md:border-gray-200/60 dark:bg-gray-900/98 dark:md:border-gray-700/60">
<div className="flex h-full flex-col overflow-hidden rounded-none border-0 bg-white shadow-2xl md:h-auto md:rounded-2xl md:border md:border-gray-200/60 dark:bg-gray-900 dark:md:border-gray-700/60">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Removing backdrop-blur-2xl and adjusting the background opacity (bg-white/98 to bg-white, dark:bg-gray-900/98 to dark:bg-gray-900) is a solid performance improvement. backdrop-blur can be a significant performance bottleneck, especially on lower-end devices, so this change helps ensure smoother rendering.

Comment on lines 275 to 281
scale: searchIconScale,
}}
className={isLoading ? "animate-pulse" : ""}
style={{ transformOrigin: "center" }}
transition={{
opacity: {
duration: prefersReducedMotion ? 0 : 1.1,
repeat: isLoading ? Number.POSITIVE_INFINITY : 0,
ease: "easeInOut",
},
scale: { duration: prefersReducedMotion ? 0 : 0.25 },
}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Replacing the Framer Motion opacity animation with className={isLoading ? "animate-pulse" : ""} for the search icon is a good optimization. CSS animations like animate-pulse are often more performant for simple effects as they can be offloaded to the GPU more effectively than JavaScript-driven animations, reducing main thread work. This aligns with the PR description's goal to simplify the search modal loading animation.

window.requestAnimationFrame(() => {
setScrolled(window.scrollY > 20);
const isScrolled = window.scrollY > 20;
setScrolled((prev) => (prev === isScrolled ? prev : isScrolled));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Optimizing the setScrolled state update with setScrolled((prev) => (prev === isScrolled ? prev : isScrolled)) is a good practice. This prevents unnecessary re-renders of the Navbar component when the scroll state (whether it's scrolled past 20px or not) hasn't actually changed, improving overall component efficiency.

Comment on lines 213 to +214
scrolled || isMenuOpen
? "border-gray-200/50 bg-white/80 backdrop-blur-xl dark:border-white/5 dark:bg-[#0a0a0a]/80"
? "border-gray-200/50 bg-white/95 backdrop-blur-sm dark:border-white/5 dark:bg-[#0a0a0a]/95"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The reduction of backdrop-blur-xl to backdrop-blur-sm and the increase in background opacity (bg-white/80 to bg-white/95, dark:bg-[#0a0a0a]/80 to dark:bg-[#0a0a0a]/95) is a positive change for performance. This directly addresses the PR's objective to reduce the impact of expensive backdrop-blur effects, leading to a smoother user interface.

Comment on lines +96 to +109
onMouseEnter={() => {
setIsHovered(true);
controls.stop();
}}
onMouseLeave={() => {
setIsHovered(false);
controls.start({
x: [`${-singleSetWidth}px`, "0px"],
transition: {
duration: 60,
ease: "linear",
repeat: Number.POSITIVE_INFINITY,
},
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The updated onMouseEnter and onMouseLeave handlers correctly integrate with Framer Motion's controls.stop() and controls.start(). This provides a clean and declarative way to manage the animation state based on user interaction, which is more robust and often more performant than manual DOM manipulation or RAF loops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants