Performance: Animationen pausieren, Footer-Raster entschärft, WebGL nachladen
- Footer-Schriftzug (FlickeringGrid): Textmaske einmal pro Größe statt ~14.500 getImageData-Aufrufe pro Frame, nur flackernde Quadrate neu zeichnen (69–86 ms -> 0,1–0,2 ms pro Frame, Darstellung pixelgleich) - PixelBlast: WebGL erst in Viewport-Nähe anlegen, unsichtbar pausieren (autoPauseOffscreen war nie angeschlossen), Shader asynchron kompilieren, beim Unmount aufräumen (Render-Schleifen liefen nach Seitenwechsel weiter); kein MSAA, keine erzwungene High-Performance-GPU - Silk (Hero): nur rendern, solange sichtbar; DPR max. 1,5 - LightRays: keine verwaiste Render-Schleife mehr bei schnellem Vorbeiscrollen - BorderGlow (Kontaktkarte): Sweep nur, solange die Karte sichtbar ist - Silk, PixelBlast, LightRays als eigene Chunks (React.lazy): Haupt-Bundle 1,6 MB -> 646 KB (gzip 470 -> 207 KB) - backgroud_effect und Emailsorter-Vorschaubild als WebP (974 KB -> 15 KB, 1,2 MB -> 11 KB), Projekt-Vorschaubilder lazy Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f74ddfb5ae
commit
5cc8b5f66b
13 files changed
+422
-264
No files matched your search
@@ -127,9 +127,18 @@ const BorderGlow = ({
|
||||
const angleStart = 110;
|
||||
const angleEnd = 465;
|
||||
let cancelled = false;
|
||||
let running = false;
|
||||
let visible = typeof IntersectionObserver === 'undefined';
|
||||
|
||||
function runSweep() {
|
||||
if (cancelled || !card) return;
|
||||
// Nur sweepen, solange die Karte im Bild ist – sonst malt der Browser
|
||||
// Maske, Verläufe und Schatten in jedem Frame umsonst neu
|
||||
if (!visible) {
|
||||
running = false;
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
card.classList.add('sweep-active');
|
||||
card.style.setProperty('--cursor-angle', `${angleStart}deg`);
|
||||
animateValue({ duration: 500, onUpdate: v => card.style.setProperty('--edge-proximity', String(v)) });
|
||||
@@ -151,8 +160,19 @@ const BorderGlow = ({
|
||||
});
|
||||
}
|
||||
|
||||
runSweep();
|
||||
return () => { cancelled = true; };
|
||||
if (visible) {
|
||||
runSweep();
|
||||
return () => { cancelled = true; };
|
||||
}
|
||||
const observer = new IntersectionObserver(([entry]) => {
|
||||
visible = entry.isIntersecting;
|
||||
if (visible && !running) runSweep();
|
||||
});
|
||||
observer.observe(card);
|
||||
return () => {
|
||||
cancelled = true;
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [animated]);
|
||||
|
||||
const glowVars = buildGlowVars(glowColor, glowIntensity);
|
||||
|
||||
Reference in new issue
Block a user