refactor: optimize button animations and interval checks for performance

This commit introduces several performance improvements across the UI components:

- Updated the Button component to enhance hover animations by grouping styles for better GPU efficiency.
- Adjusted the interval timing in the BoardView and WorktreePanel components from 1 second to 3 and 5 seconds respectively, reducing CPU/GPU usage.
- Replaced the continuous gradient rotation animation with a subtle pulse effect in global CSS to further optimize rendering performance.

These changes aim to improve the overall responsiveness and efficiency of the UI components.
This commit is contained in:
SuperComboGamer
2025-12-20 23:46:24 -05:00
parent 5aedb4fadf
commit 012d1c452b
4 changed files with 23 additions and 19 deletions

View File

@@ -72,15 +72,15 @@ function Button({
<button <button
className={cn( className={cn(
buttonVariants({ variant, size }), buttonVariants({ variant, size }),
"p-[1px]", // Force 1px padding for the gradient border "group p-[1px]", // Force 1px padding for the gradient border, group for hover animation
className className
)} )}
data-slot="button" data-slot="button"
disabled={isDisabled} disabled={isDisabled}
{...props} {...props}
> >
{/* Animated rotating gradient border - smoother animation */} {/* Animated rotating gradient border - only animates on hover for GPU efficiency */}
<span className="absolute inset-[-1000%] animate-[spin_3s_linear_infinite] animated-outline-gradient opacity-75 transition-opacity duration-300 group-hover:opacity-100" /> <span className="absolute inset-[-1000%] animated-outline-gradient opacity-75 transition-opacity duration-300 group-hover:animate-[spin_3s_linear_infinite] group-hover:opacity-100" />
{/* Inner content container */} {/* Inner content container */}
<span <span

View File

@@ -728,7 +728,7 @@ export function BoardView() {
// Check immediately, then every 3 seconds // Check immediately, then every 3 seconds
checkAndStartFeatures(); checkAndStartFeatures();
const interval = setInterval(checkAndStartFeatures, 1000); const interval = setInterval(checkAndStartFeatures, 3000);
return () => { return () => {
// Mark as inactive to prevent any pending async operations from continuing // Mark as inactive to prevent any pending async operations from continuing

View File

@@ -102,12 +102,13 @@ export function WorktreePanel({
const toggleCollapsed = () => setIsCollapsed((prev) => !prev); const toggleCollapsed = () => setIsCollapsed((prev) => !prev);
// Periodic interval check (1 second) to detect branch changes on disk // Periodic interval check (5 seconds) to detect branch changes on disk
// Reduced from 1s to 5s to minimize GPU/CPU usage from frequent re-renders
const intervalRef = useRef<NodeJS.Timeout | null>(null); const intervalRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => { useEffect(() => {
intervalRef.current = setInterval(() => { intervalRef.current = setInterval(() => {
fetchWorktrees({ silent: true }); fetchWorktrees({ silent: true });
}, 1000); }, 5000);
return () => { return () => {
if (intervalRef.current) { if (intervalRef.current) {

View File

@@ -597,15 +597,13 @@
} }
/* Animated border for in-progress cards */ /* Animated border for in-progress cards */
@keyframes border-rotate { /* Using a subtle pulse animation instead of continuous gradient rotation for GPU efficiency */
0% { @keyframes border-pulse {
background-position: 0% 50%; 0%, 100% {
opacity: 0.7;
} }
50% { 50% {
background-position: 100% 50%; opacity: 1;
}
100% {
background-position: 0% 50%;
} }
} }
@@ -614,15 +612,20 @@
border-radius: 0.75rem; border-radius: 0.75rem;
padding: 2px; padding: 2px;
background: linear-gradient( background: linear-gradient(
90deg, 135deg,
var(--running-indicator), var(--running-indicator),
color-mix(in oklch, var(--running-indicator), transparent 50%), color-mix(in oklch, var(--running-indicator), transparent 30%),
var(--running-indicator),
color-mix(in oklch, var(--running-indicator), transparent 50%),
var(--running-indicator) var(--running-indicator)
); );
background-size: 200% 100%; animation: border-pulse 2s ease-in-out infinite;
animation: border-rotate 3s ease infinite; }
/* Pause animation when user prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
.animated-border-wrapper {
animation: none;
opacity: 1;
}
} }
.animated-border-wrapper > * { .animated-border-wrapper > * {