perf: fix GPU-heavy CSS patterns

- Remove mix-blend-mode: overlay from body::before noise texture
  (was forcing fullscreen GPU compositing on every paint)
- Disable noise texture on mobile via display:none media query
- Replace backdrop-filter animation in backdropFadeIn/Out keyframes
  with opacity-only animation (backdrop-filter transition is expensive)
- Replace toast progress bar width animation with scaleX (GPU-composited)
- Remove redundant will-change: transform from .glass and .wave-blob
This commit is contained in:
Fringg
2026-02-23 17:14:57 +03:00
parent 9a84e13e6c
commit 860493058a
2 changed files with 14 additions and 15 deletions

View File

@@ -221,9 +221,10 @@ function ToastItem({ toast, onClose }: { toast: Toast; onClose: () => void }) {
{/* Progress bar */} {/* Progress bar */}
<div className="absolute bottom-0 left-0 right-0 h-1 bg-dark-800/50"> <div className="absolute bottom-0 left-0 right-0 h-1 bg-dark-800/50">
<div <div
className={`h-full ${style.progress} opacity-60`} className={`h-full w-full ${style.progress} opacity-60`}
style={{ style={{
animation: `shrink ${toast.duration}ms linear forwards`, animation: `shrink ${toast.duration}ms linear forwards`,
transformOrigin: 'left',
}} }}
/> />
</div> </div>

View File

@@ -192,7 +192,7 @@
position: relative; position: relative;
} }
/* Global Noise Texture */ /* Global Noise Texture — no mix-blend-mode to avoid fullscreen GPU compositing */
body::before { body::before {
content: ''; content: '';
position: fixed; position: fixed;
@@ -201,7 +201,13 @@
pointer-events: none; pointer-events: none;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
opacity: 0.03; opacity: 0.03;
mix-blend-mode: overlay; }
/* Disable noise on mobile to save GPU */
@media (max-width: 1023px) {
body::before {
display: none;
}
} }
/* Optimize main scrollable content */ /* Optimize main scrollable content */
@@ -440,9 +446,7 @@ img.twemoji {
/* Glass effect - Dark (optimized for mobile) */ /* Glass effect - Dark (optimized for mobile) */
.glass { .glass {
@apply border border-dark-700/30 bg-dark-900/80; @apply border border-dark-700/30 bg-dark-900/80;
/* GPU acceleration */
transform: translateZ(0); transform: translateZ(0);
will-change: transform;
} }
/* Enable backdrop-blur only on desktop where it's performant */ /* Enable backdrop-blur only on desktop where it's performant */
@@ -1431,13 +1435,13 @@ input[type='checkbox']:hover:not(:checked) {
animation: wheel-glow 2s ease-in-out infinite; animation: wheel-glow 2s ease-in-out infinite;
} }
/* Toast progress bar animation */ /* Toast progress bar animation — use scaleX instead of width to avoid layout thrashing */
@keyframes shrink { @keyframes shrink {
from { from {
width: 100%; transform: scaleX(1);
} }
to { to {
width: 0%; transform: scaleX(0);
} }
} }
@@ -1454,10 +1458,8 @@ input[type='checkbox']:hover:not(:checked) {
.wave-blob { .wave-blob {
position: absolute; position: absolute;
border-radius: 50%; border-radius: 50%;
filter: blur(60px); /* Reduced from 80px for better performance */ filter: blur(60px);
opacity: 0.5; opacity: 0.5;
/* GPU acceleration */
will-change: transform;
transform: translateZ(0); transform: translateZ(0);
backface-visibility: hidden; backface-visibility: hidden;
} }
@@ -1644,22 +1646,18 @@ input[type='checkbox']:hover:not(:checked) {
@keyframes backdropFadeIn { @keyframes backdropFadeIn {
from { from {
opacity: 0; opacity: 0;
backdrop-filter: blur(0);
} }
to { to {
opacity: 1; opacity: 1;
backdrop-filter: blur(8px);
} }
} }
@keyframes backdropFadeOut { @keyframes backdropFadeOut {
from { from {
opacity: 1; opacity: 1;
backdrop-filter: blur(8px);
} }
to { to {
opacity: 0; opacity: 0;
backdrop-filter: blur(0);
} }
} }