Communitygithub.com

Blaise1030/astro-marketing

Optimieren Sie die Web-Performance für schnellere Ladezeiten und eine bessere Benutzererfahrung. Verwenden Sie diese Fähigkeit bei Anfragen wie „Website beschleunigen“, „Performance optimieren“, „Ladezeit reduzieren“, „Langsames Laden beheben“, „Seitengeschwindigkeit verbessern“ oder „Performance-Audit“.

Was ist astro-marketing?

Diese Fähigkeit führt evidenzbasierte Performance-Optimierungen durch, die auf echten Benutzersignalen (Feldsignale) und Browser-Traces (Labordaten) basieren. Sie priorisiert die Verbesserung von Core Web Vitals wie LCP, INP und CLS, indem sie mit einem reproduzierbaren Mess-Workflow arbeitet (siehe references/MEASUREMENT.md). Der Entwickler nutzt Chrome DevTools MCP (performance_start_trace, performance_analyze_insight), um gezielt Engpässe zu identifizieren und nur die relevanten Code- oder Asset-Änderungen vorzunehmen. Die Fähigkeit deckt alle wesentlichen Optimierungsbereiche ab: Server-Antwort (TTFB, Kompression, Early Hints), Ressourcenladung (Preconnect, Preload, Prerender mit Speculation Rules), JavaScript (Defer, Code-Splitting, Tree Shaking), Bilder (Formate, responsive Bilder, LCP-Priorität), Schriften (font-display, Variable Fonts), Caching (Cache-Control, Service Worker), Laufzeit-Performance (Layout Thrashing vermeiden, Debouncing, requestAnimationFrame, Virtualisierung, View Transitions) sowie Drittanbieter-Skripte (async, verzögertes Laden, Fassadenmuster). Die Ergebnisse werden stets durch Vorher/Nachher-Messungen dokumentiert, wobei Feldverifikation abgewartet wird.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Blaise1030/astro-marketing/tree/HEAD/.agents/skills/performance

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Vorschau

Aus dem Skill-README

astro-marketing preview
astro-marketing preview
astro-marketing preview
astro-marketing preview

Dokumentation

Performance-Optimierung

Evidenzbasierte Performance-Optimierung unter Verwendung von echten Benutzersignalen für die Priorisierung und Browser-Traces für die Diagnose. Der Fokus liegt auf Ladegeschwindigkeit, Laufzeit-Reaktionsfähigkeit und Ressourcenauslieferung.

Funktionsweise

  1. Wenn eine Seite ausgeführt werden kann, lesen Sie den Mess-Workflow und erstellen Sie eine Feld-plus-Labor-Baseline vor der Bearbeitung.
  2. Priorisieren Sie schlechte Core Web Vitals von echten Nutzern. Verwenden Sie einen DevTools-Performance-Trace und dessen fokussierte Einblicke, um die Ursache zu finden.
  3. Inspizieren und ändern Sie nur den Code oder die Assets, die mit den gemessenen Engpässen verbunden sind.
  4. Führen Sie erneute äquivalente Labormessungen durch und berichten Sie Vorher/Nachher-Werte, Bedingungen und Unsicherheit. Die Feldverifikation bleibt ausstehend, bis genügend neue Nutzerdaten eintreffen.

Wenn keine ausführbare Seite vorhanden ist, führen Sie eine statische Inspektion durch, bezeichnen Sie die Ergebnisse jedoch als Hypothesen, nicht als gemessene Regressionen. Fügen Sie den Befehl oder den Browser-Workflow hinzu, mit dem jede Hypothese mit hoher Auswirkung überprüft werden kann.

Bevorzugen Sie ein Browser-Tool, das einen Performance-Trace aufzeichnet und fokussierte Einblicke liefert. Verwenden Sie mit Chrome DevTools MCP performance_start_trace und performance_analyze_insight; leiten Sie Performance nicht über lighthouse_audit, da dies nicht-Performance-Kategorien von Lighthouse abdeckt.

Startendes Performance-Budget

Budgets müssen die Zielgeräte, Netzwerke, Seitentypen und Nutzerreisen des Produkts widerspiegeln. Die folgenden Werte sind anfängliche Leitplanken für eine typische Inhalts- oder Commerce-Seite, keine universellen Bestehen/Nichtbestehen-Kriterien. Behalten Sie ein vorhandenes Projektbudget bei, wenn bereits eines definiert ist.

RessourceBudgetBegründung
Gesamtseitengewicht< 1,5 MBBegrenzt Übertragungszeit und Datenkosten in eingeschränkten Zielnetzwerken; mit repräsentativen Seiten kalibrieren
JavaScript (komprimiert)< 300 KBSchützt Parse- und Ausführungskosten
CSS (komprimiert)< 100 KBBegrenzt render-blockierende Arbeit
Bilder (above-fold)< 500 KBSchützt wahrscheinliche LCP-Ressourcen
Schriften< 100 KBBegrenzt kritische Schriftübertragung
Drittanbieter< 200 KBBegrenzt Code außerhalb der Produktkontrolle

Kritischer Rendering-Pfad

Server-Antwort

  • TTFB < 800ms. Die Time to First Byte sollte schnell sein. Verwenden Sie CDN, Caching und effiziente Backends.
  • Komprimierung aktivieren. Gzip oder Brotli für Text-Assets. Brotli bevorzugt (15-20 % kleiner).
  • HTTP/2 oder HTTP/3. Multiplexing reduziert den Verbindungsaufwand.
  • Edge-Caching. Cachen Sie HTML nach Möglichkeit am CDN-Edge.
  • Early Hints (HTTP 103) bei gemessener Dokumentlatenz in Betracht ziehen. Wenn ein Trace eine langsame HTML-Generierung und stabile kritische Unterressourcen zeigt, senden Sie eine vorläufige 103 mit Link-Headern vor der normalen endgültigen Antwort von derselben Anfrage. Verwenden Sie HTTP/2 oder höher. Ein CDN kann die 103 aus Link-Headern auf eine frühere 200 synthetisieren, oder der Ursprungs-/Edge-Handler kann sie direkt ausgeben. Nicht unterstützte Clients fahren mit der endgültigen Antwort fort, aber bestätigen Sie die aktuelle Browser- und Infrastrukturunterstützung. Beschränken Sie Hinweise auf nachgewiesene kritische Preloads oder Preconnects: ungenaue Hinweise verschwenden Bandbreite. Cloudflare berichtete eine 20-30%ige LCP-Verbesserung in einem künstlichen, bildlastigen Test; behandeln Sie dies als eine Anbieter-Fallstudie, nicht als erwartete Einsparung, und messen Sie Ihr Ergebnis. Siehe MDNs 103-Implementierungsbeispiel und die Cloudflare-Studie.

Ressourcenladen

Preconnect zu erforderlichen Ursprüngen:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>

Kritische Ressourcen vorladen:

Laden Sie nur Ressourcen vor, deren späte Entdeckung im Trace sichtbar ist. Jeder Preload konkurriert um Bandbreite, und eine unnötige hochpriorisierte Anfrage kann LCP verzögern.

<!-- LCP-Bild -->
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">

<!-- Kritische Schrift -->
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>

Prerender von wahrscheinlichen nächsten Navigationen mit der Speculation Rules API:

<script type="speculationrules">
{
  "prerender": [{
    "where": { "href_matches": "/*" },
    "eagerness": "moderate"
  }]
}
</script>

moderate wartet auf ein stärkeres Intent-Signal als die eifrigen Modi. Messen Sie die Vorhersagetrefferquote, übertragene Bytes und Serverkosten; ein falscher Prerender ist ungefähr eine ungenutzte Navigation. Siehe core-web-vitals → LCP für die Abwägungen und die für Analysen erforderliche prerenderingchange-Absicherung.

Nicht-kritisches CSS aufschieben:

<!-- Kritisches CSS inline -->
<style>/* Above-fold-Stile */</style>

<!-- Nicht-kritisches CSS -->
<link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>

JavaScript-Optimierung

Nicht-essentielle Skripte aufschieben:

<!-- Parser-blockierend (vermeiden) -->
<script src="/critical.js"></script>

<!-- Aufgeschoben (bevorzugt) -->
<script defer src="/app.js"></script>

<!-- Async (für unabhängige Skripte) -->
<script async src="/analytics.js"></script>

<!-- Modul (standardmäßig aufgeschoben) -->
<script type="module" src="/app.mjs"></script>

Code-Splitting-Muster:

// Routenbasiertes Splitting
const Dashboard = lazy(() => import('./Dashboard'));

// Komponentenbasiertes Splitting
const HeavyChart = lazy(() => import('./HeavyChart'));

// Feature-basiertes Splitting
if (user.isPremium) {
  const PremiumFeatures = await import('./PremiumFeatures');
}

Tree-Shaking Best Practices:

// ❌ Importiert gesamte Bibliothek
import _ from 'lodash';
_.debounce(fn, 300);

// ✅ Importiert nur, was benötigt wird
import debounce from 'lodash/debounce';
debounce(fn, 300);

Bildoptimierung

Formatauswahl

FormatAnwendungsfallBrowserunterstützung
AVIFFotos, beste Komprimierung92%+
WebPFotos, guter Fallback97%+
PNGGrafiken mit TransparenzUniversell
SVGSymbole, Logos, IllustrationenUniversell

Responsive Bilder

<picture>
  <!-- AVIF für moderne Browser -->
  <source 
    type="image/avif"
    srcset="hero-400.avif 400w,
            hero-800.avif 800w,
            hero-1200.avif 1200w"
    sizes="(max-width: 600px) 100vw, 50vw">
  
  <!-- WebP-Fallback -->
  <source 
    type="image/webp"
    srcset="hero-400.webp 400w,
            hero-800.webp 800w,
            hero-1200.webp 1200w"
    sizes="(max-width: 600px) 100vw, 50vw">
  
  <!-- JPEG-Fallback -->
  <img 
    src="hero-800.jpg"
    srcset="hero-400.jpg 400w,
            hero-800.jpg 800w,
            hero-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw, 50vw"
    width="1200" 
    height="600"
    alt="Hero-Bild"
    loading="lazy"
    decoding="async">
</picture>

LCP-Bildpriorität

<!-- Above-fold-LCP-Bild: eager loading, hohe Priorität -->
<img 
  src="hero.webp" 
  fetchpriority="high"
  loading="eager"
  decoding="sync"
  alt="Hero">

<!-- Below-fold-Bilder: lazy loading -->
<img 
  src="product.webp" 
  loading="lazy"
  decoding="async"
  alt="Produkt">

Schriftoptimierung

Ladestrategie

/* System-Schriftarten-Stapel als Fallback */
body {
  font-family: 'Custom Font', -apple-system, BlinkMacSystemFont, 
               'Segoe UI', Roboto, sans-serif;
}

/* Unsichtbaren Text verhindern */
@font-face {
  font-family: 'Custom Font';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap; /* oder optional für nicht-kritische Schriften */
  font-weight: 400;
  font-style: normal;
  unicode-range: U+0000-00FF; /* Auf lateinische Zeichen beschränken */
}

Kritische Schriften vorladen

<link rel="preload" href="/fonts/heading.woff2" as="font" type="font/woff2" crossorigin>

Variable Fonts

/* Eine Datei statt mehrerer Schriftstärken */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
}

Caching-Strategie

Cache-Control-Header

# HTML (kurz oder kein Cache)
Cache-Control: no-cache, must-revalidate

# Statische Assets mit Hash (unveränderlich)
Cache-Control: public, max-age=31536000, immutable

# Statische Assets ohne Hash
Cache-Control: public, max-age=86400, stale-while-revalidate=604800

# API-Antworten
Cache-Control: private, max-age=0, must-revalidate

Service Worker Caching

// Cache-first für statische Assets
self.addEventListener('fetch', (event) => {
  if (event.request.destination === 'image' ||
      event.request.destination === 'style' ||
      event.request.destination === 'script') {
    event.respondWith(
      caches.match(event.request).then((cached) => {
        return cached || fetch(event.request).then((response) => {
          const clone = response.clone();
          caches.open('static-v1').then((cache) => cache.put(event.request, clone));
          return response;
        });
      })
    );
  }
});

Laufzeit-Performance

Layout Thrashing vermeiden

// ❌ Erzwingt mehrere Reflows
elements.forEach(el => {
  const height = el.offsetHeight; // Lesen
  el.style.height = height + 10 + 'px'; // Schreiben
});

// ✅ Alle Lesevorgänge bündeln, dann alle Schreibvorgänge
const heights = elements.map(el => el.offsetHeight); // Alle Lesevorgänge
elements.forEach((el, i) => {
  el.style.height = heights[i] + 10 + 'px'; // Alle Schreibvorgänge
});

Teure Operationen entprellen (Debounce)

function debounce(fn, delay) {
  let timeout;
  return (...args) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => fn(...args), delay);
  };
}

// Scroll/Resize-Handler entprellen
window.addEventListener('scroll', debounce(handleScroll, 100));

requestAnimationFrame verwenden

// ❌ Kann Ruckeln verursachen
setInterval(animate, 16);

// ✅ Mit Bildschirmaktualisierung synchronisiert
function animate() {
  // Animationslogik
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

Lange Listen virtualisieren

// Für Listen > 100 Elemente nur sichtbare Elemente rendern
// Bibliotheken wie react-window, vue-virtual-scroller oder natives CSS verwenden:
.virtual-list {
  content-visibility: auto;
  contain-intrinsic-size: 0 50px; /* Geschätzte Elementhöhe */
}

Sanfte Navigationen mit View Transitions

Die View Transitions API ermöglicht es dem Browser, zwischen zwei DOM-Zuständen mit einem einzigen GPU-komponierten Snapshot überzublenden (oder benutzerdefiniert zu animieren) – kein Double-Render, kein Layout Thrashing, und der Snapshot zählt nicht zum CLS.

Gleiches Dokument (SPA-Stil) – Baseline 2026:

// Die DOM-Mutation umschließen, die die Ansicht wechselt
function navigate(newView) {
  if (!document.startViewTransition) return swapDOM(newView);
  document.startViewTransition(() => swapDOM(newView));
}

Dokumentübergreifend (MPA-Stil) – Chromium-stabil, progressive Verbesserung anderswo:

/* Auf Quell- und Zielseite */
@view-transition { navigation: auto; }

Das ist die gesamte Integration – gleichartige Navigationen werden nun automatisch eingeblendet. Um bestimmte Elemente für Shared-Element-Übergänge zu optimieren (z.B. eine Miniaturansicht, die zu einem Hero-Bild wird), geben Sie ihnen einen passenden view-transition-name:

.product-thumb[data-id="42"], .product-hero { view-transition-name: product-42; }

Kombinieren Sie dies mit Speculation Rules (oben) für sofortige und animierte Navigationen.

Drittanbieter-Skripte

Ladestrategien

// ❌ Blockiert den Hauptthread
<script src="https://analytics.example.com/script.js"></script>

// ✅ Asynchrones Laden
<script async src="https://analytics.example.com/script.js"></script>

// ✅ Verzögert bis zur Interaktion
<script>
document.addEventListener('DOMContentLoaded', () => {
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      const script = document.createElement('script');
      script.src = 'https://widget.example.com/embed.js';
      document.body.appendChild(script);
      observer.disconnect();
    }
  });
  observer.observe(document.querySelector('#widget-container'));
});
</script>

Fassadenmuster

<!-- Statischen Platzhalter bis zur Interaktion anzeigen -->
<div class="youtube-facade" 
     data-video-id="abc123" 
     onclick="loadYouTube(this)">
  <img src="/thumbnails/abc123.jpg" alt="Videotitel">
  <button aria-label="Video abspielen">▶</button>
</div>

Messung

Verwenden Sie den Mess-Workflow, sobald eine URL ausführbar ist. Er definiert das Chrome DevTools MCP-Routing, CrUX- und Fallback-Quellen, wiederholbare Laborbedingungen und ein kompaktes Nachweisformat.

MetrikArtInterpretation
LCP, INP, CLS bei p75FeldCore Web Vitals des Nutzerergebnisses; zur Bestehen/Nichtbestehen-Priorisierung verwenden
LCP, CLS in einem TraceLaborReproduzierbare Diagnosewerte für eine Navigation
TBTLaborDiagnose der Hauptthread-Blockierung und grober INP-Proxy, nicht Feld-INP
FCP, Speed IndexLaborLade-Diagnostik, keine Core Web Vitals

Rohe PerformanceObserver-Schnipsel sind für die aktuelle Browser-Sitzung nützlich, aber an sich keine echten Nutzerdaten. Wenn der Benutzer Produktionstelemetrie wünscht, lesen Sie die Erstanbieter-RUM-Referenz und bevorzugen Sie web-vitals gegenüber einer handgestrickten Metrikimplementierung.

Referenzen

Für spezifische Core Web Vitals Optimierungen siehe Core Web Vitals.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Verwandte Skills