Performance ist ein Kernfeature, kein Nachgedanke. Eine Verzögerung von 100ms bei der Ladezeit kann Conversions um 7% senken. Eine Seite, die in 1 Sekunde lädt, hat eine 3x höhere Conversion-Rate als eine, die 5 Sekunden braucht. Und seit 2021 nutzt Google Core Web Vitals als direktes Ranking-Signal — langsame Seiten ranken buchstäblich schlechter.
Dieser Guide deckt alles ab, was du für exzellente Scores brauchst: die drei Metriken, die Google misst, die architektonischen Entscheidungen, die Astro einzigartig schnell machen, und die konkreten Optimierungstechniken für Bilder, CSS, JavaScript, Fonts und Drittanbieter-Skripte.
Performance ist kein technisches Problem. Es ist eine Design-Einschränkung, die jede Entscheidung beeinflusst.
Core Web Vitals: Die drei Metriken
Google misst drei spezifische Metriken, die die Nutzererfahrung bei Laden, Interaktivität und visueller Stabilität repräsentieren.
Misst, wie schnell das größte sichtbare Element (Hero-Bild, Überschrift, Video-Thumbnail) auf dem Bildschirm erscheint. Ziel: unter 2,5 Sekunden. Das ist die Metrik, die Nutzer am meisten spüren — sie bestimmt, wie schnell die Seite „geladen aussieht". Das LCP-Element ist typischerweise ein Hero-Bild, eine große Überschrift oder ein Video-Poster.
Misst die Reaktionsfähigkeit — wie schnell die Seite auf Nutzereingaben reagiert (Klicks, Tippen, Tastatureingaben). Ziel: unter 200 Millisekunden. INP ersetzte FID im März 2024, weil es ALLE Interaktionen während des gesamten Seitenlebenszyklus misst, nicht nur die erste. Schweres JavaScript ist der Hauptfeind guter INP-Scores.
Misst die visuelle Stabilität — wie stark sich Seiteninhalt während des Ladens unerwartet verschiebt. Ziel: unter 0,1. Nichts frustriert Nutzer mehr, als auf einen Button zu klicken und die Seite springt, sodass man etwas anderes klickt. Bilder ohne Dimensionen, spät ladende Fonts und eingefügte Werbung sind die Hauptschuldigen.
Warum Astro für Performance gebaut ist
Astros Architektur unterscheidet sich grundlegend von React, Next.js oder Nuxt. Es liefert standardmäßig null JavaScript aus. Jede Seite wird zur Build-Time als statisches HTML gerendert, ohne Hydration-Overhead.
| Framework | Standard-JS Recommended | Hydration | LCP-Einfluss |
|---|---|---|---|
| Astro (statisch) | 0 KB | Keine (statisches HTML) | Exzellent |
| Astro (Islands) | Pro Island | Selektiv | Exzellent |
| Next.js (App Router) | 85–120 KB | Ganze Seite | Gut |
| Nuxt 3 | 70–100 KB | Ganze Seite | Gut |
| Create React App | 150–250 KB | Ganze Seite | Schlecht |
| WordPress (Durchschnitt) | 200–400 KB | Plugin-abhängig | Schlecht |
Astros Island-Architektur bedeutet, dass interaktive Komponenten (ein Formular, ein Karussell, eine Suche) einzeln hydriert werden. Der Rest der Seite — Header, Footer, Inhalt, Navigation — bleibt als reines HTML. Deshalb erreichen Astro-Seiten konsistent 95–100 bei Lighthouse ohne jegliche Optimierungsarbeit.
LCP-Optimierung
Der Largest Contentful Paint ist meist die größte Herausforderung. Hier die Strategien nach Wirkung sortiert:
Identifiziere dein LCP-Element (meist Hero-Bild). Preloade es mit <link rel="preload">. Liefere es in WebP/AVIF. Setze explizite width/height. Lazy-loade das LCP-Bild niemals.
Kritisches CSS inline einbinden. Nicht-kritische Stylesheets deferren. Ungenutztes CSS entfernen. <link rel="preconnect"> für externe Origins verwenden.
CDN verwenden (Netlify, Vercel, Cloudflare). Kompression aktivieren (Brotli > gzip). Far-Future Cache-Header für statische Assets setzen.
font-display: swap verwenden. Kritische Font-Dateien preloaden. Fonts auf benötigte Zeichen subsetten. Self-hosten statt Google Fonts für weniger Verbindungen.
Bildoptimierung im Detail
Bilder sind das LCP-Element auf 70% aller Webseiten. Sie richtig zu optimieren hat den größten einzelnen Einfluss auf die wahrgenommene Performance.
---
/* Astros eingebaute Image-Komponente übernimmt die Optimierung */
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<!-- Automatisch WebP/AVIF, responsives srcset, width/height -->
<Image
src={heroImage}
alt="Hero-Bildbeschreibung"
widths={[400, 800, 1200]}
sizes="(max-width: 768px) 100vw, 1200px"
loading="eager"
fetchpriority="high"
/> <!-- Manuelles responsives Bild mit Art Direction -->
<picture>
<source
type="image/avif"
srcset="/images/hero-400.avif 400w,
/images/hero-800.avif 800w,
/images/hero-1200.avif 1200w"
sizes="(max-width: 768px) 100vw, 1200px"
/>
<source
type="image/webp"
srcset="/images/hero-400.webp 400w,
/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w"
sizes="(max-width: 768px) 100vw, 1200px"
/>
<img src="/images/hero-800.jpg" alt="Hero" width="1200" height="630"
loading="eager" fetchpriority="high" decoding="async" />
</picture> <!-- Im <head>: LCP-Bild preloaden für schnellste Auslieferung -->
<link
rel="preload"
as="image"
type="image/webp"
href="/images/hero-1200.webp"
imagesrcset="/images/hero-400.webp 400w,
/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w"
imagesizes="(max-width: 768px) 100vw, 1200px"
fetchpriority="high"
/> INP-Optimierung
Interaction to Next Paint misst, wie reaktionsfähig deine Seite sich anfühlt. Jeder Klick, jedes Tippen und jede Tastatureingabe wird ausgewertet.
Die Hauptursache für schlechte INP-Werte ist zu viel JavaScript auf dem Main Thread. Jedes KB JS muss geparst, kompiliert und ausgeführt werden, bevor der Browser auf Nutzereingaben reagieren kann. Astros Zero-JS-Standard löst das für die meisten Seiten. Für interaktive Islands: halte jede Island unter 50 KB. Nutze dynamische Imports: client:visible hydriert erst, wenn die Komponente ins Sichtfeld scrollt.
Lang laufendes JavaScript blockiert den Main Thread. Wenn eine Funktion 300ms braucht, kann der Browser in dieser Zeit nicht auf Klicks reagieren. Zerlege lange Tasks in kleinere Stücke mit requestAnimationFrame() oder setTimeout(0). Das gibt die Kontrolle zwischen den Chunks an den Browser zurück und hält Interaktionen responsiv. Ziel: kein einzelner Task über 50ms.
Suchfelder, Filtersteuerungen und Scroll-Handler feuern Events schnell. Ohne Debouncing löst jeder Tastendruck teure Operationen aus (DOM-Abfragen, Re-Renders, API-Calls). Debounce Input-Handler mit 150–300ms Verzögerung. Verwende requestAnimationFrame() für Scroll-Handler. Das reduziert die Arbeit pro Interaktion drastisch.
JavaScript-Budget
| Ressource | Budget | Einfluss Recommended |
|---|---|---|
| Gesamt-JS pro Route | < 170 KB gzipped | INP + LCP |
| Einzelne Island | < 50 KB gzipped | INP |
| Drittanbieter-Skripte | < 50 KB gesamt | INP + LCP |
| Main-Thread-Arbeit | < 50ms pro Task | INP |
| Total Blocking Time | < 200ms | INP (Lab-Proxy) |
CLS-Optimierung
Layout-Verschiebungen passieren, wenn sichtbare Elemente nach dem initialen Render ihre Position ändern. Wie du mit reinen CSS-Animationen statt JavaScript-Bibliotheken Layout-Shifts komplett vermeidest, zeigt mein SVG-Artikel. Aus Nutzerperspektive sind sie das frustrierendste Performance-Problem.
Layout-Verschiebungen eliminieren
- Immer Bilddimensionen setzen
Jedes <img> und <video> muss explizite width- und height-Attribute haben (oder CSS aspect-ratio). Der Browser reserviert den korrekten Platz, bevor das Asset lädt — keine Verschiebungen.
- font-display: swap klug einsetzen
Swap verhindert unsichtbaren Text, aber der Font-Wechsel selbst kann eine Verschiebung verursachen, wenn Fallback und Web-Font unterschiedliche Metriken haben. Nutze die CSS size-adjust-Eigenschaft in @font-face, um die Fallback-Font-Metriken anzugleichen.
- Platz für dynamischen Inhalt reservieren
Werbung, Embeds, Cookie-Banner und lazy-geladene Komponenten müssen eine definierte min-height oder aspect-ratio haben, bevor sie laden. Niemals Inhalt über bestehendem Inhalt einfügen ohne Nutzerinteraktion.
- Banner nicht oben einfügen
Ein Cookie-Consent-Banner, das die Seite nach unten drückt, verursacht einen massiven CLS-Spike. Verwende fixed/sticky Positionierung oder Overlay-Muster, die bestehenden Inhalt nicht verschieben.
- Nur mit transform animieren
CSS-Eigenschaften wie top, left, width und height lösen Layout-Neuberechnungen aus. Nutze transform: translateX/Y und opacity für Animationen. Diese werden auf der GPU composited und verursachen nie Layout-Verschiebungen.
CSS-Performance-Strategie
<!-- Kritisches CSS inline: Styles für Above-the-Fold-Inhalt -->
<style>
/* Base-Reset, Layout, Header, Hero, Typografie */
/* Unter 14 KB halten (ein TCP Round-Trip) */
:root { --color-bg: #f9fafb; --color-text: #111827; }
body { font-family: system-ui; color: var(--color-text); }
.header { display: flex; align-items: center; }
.hero { min-height: 60vh; }
</style> <!-- Nicht-kritisches CSS mit media print Trick deferren -->
<link
rel="stylesheet"
href="/styles/below-fold.css"
media="print"
onload="this.media='all'"
/>
<noscript>
<link rel="stylesheet" href="/styles/below-fold.css" />
</noscript> /* Optimiertes Font Loading mit Metrik-Overrides */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2');
font-weight: 100 900;
font-display: swap;
size-adjust: 107%; /* Fallback-Metriken angleichen */
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
} Performance-Mess-Workflow
Zu wissen, was und wie man misst, ist die halbe Miete. Nutze Lab-Tools zum Debuggen und Felddaten für die Wahrheit.
Lighthouse (Chrome DevTools, CI): synthetische Tests unter kontrollierten Bedingungen. Ideal zum Identifizieren spezifischer Probleme. Im Inkognito-Modus ausführen, ohne Erweiterungen, mit gedrosselter Verbindung (Slow 4G). Fokus auf die Performance-Score-Aufschlüsselung, nicht nur die Gesamtzahl. WebPageTest liefert Filmstreifen-Vergleiche, Wasserfall-Diagramme und mehrstufige Tests.
Chrome UX Report (CrUX): echte Nutzerdaten, gesammelt von Chrome-Nutzern, die zugestimmt haben. Das ist, was Google tatsächlich fürs Ranking verwendet. Zugang über PageSpeed Insights, Search Console oder die CrUX API. Felddaten spiegeln deine tatsächlichen Nutzer auf ihren echten Geräten und Verbindungen wider — es ist die Grundwahrheit.
Richte automatisiertes Lighthouse CI in deiner Deployment-Pipeline ein. Jede PR durchläuft ein Performance-Audit. Setze Budgets: LCP unter 2,5s, INP unter 200ms, CLS unter 0,1, Gesamt-JS unter 170 KB. Lasse den Build fehlschlagen, wenn Budgets überschritten werden. Überwache CrUX-Daten monatlich über die Search Console, um Regressionen in der realen Performance zu erkennen.
Die Performance-Checkliste
WebP/AVIF-Formate. Explizite Dimensionen. Responsives srcset. LCP eager laden. Below-fold lazy laden.
Self-hosted WOFF2. font-display: swap. Kritische Fonts preloaden. size-adjust für CLS-Prävention.
Kritisches CSS inline. Nicht-kritisches deferren. Unter 50 KB kritischer Pfad. Keine ungenutzten Styles.
Unter 170 KB pro Route. Islands für Interaktivität. Dynamische Imports. Kein Main-Thread-Blocking.
CDN-Auslieferung. Brotli-Kompression. Cache-Header. Preconnect für externe Origins.
Lighthouse CI in Pipeline. CrUX-Felddaten monatlich. Performance-Budgets durchgesetzt.
Häufige Fehler
Frequently Asked Questions
Lighthouse läuft auf deinem schnellen Entwickler-Rechner mit simulierter Drosselung. Echte Nutzer sind auf 3 Jahre alten Android-Handys mit 3G-Verbindung. Prüfe immer CrUX-Felddaten (über PageSpeed Insights oder Search Console). Das 75. Perzentil echter Nutzer ist, was Google fürs Ranking verwendet — nicht dein lokaler Lighthouse-Score.
Nein. Das LCP-Bild (meist das Hero-Bild) muss eager geladen werden mit fetchpriority="high". Lazy-loade nur Bilder, die below the fold sind — Bilder, die der Nutzer erst beim Scrollen sieht. Lazy Loading des LCP-Bilds fügt 200–500ms zur LCP-Zeit hinzu.
Astro gibt dir eine exzellente Ausgangsbasis (kein JS, statisches HTML, scoped CSS). Aber du kannst trotzdem eine langsame Seite haben mit unoptimerten Bildern, zu vielen Drittanbieter-Skripten, render-blockenden Stylesheets oder einem langsamen Hosting-Anbieter. Astro übernimmt die Framework-Level-Performance — du übernimmst die Content-Level-Performance.
Erheblich. Eine statische Seite auf einem CDN (Netlify, Vercel, Cloudflare Pages) hat eine TTFB von 20–50ms weltweit. Dieselbe Seite auf einem Single-Region Shared Host kann 200–800ms TTFB haben. Für statische Astro-Seiten: immer ein CDN verwenden. Der Unterschied beträgt oft 500ms+ beim LCP.
Performance-Zeitplan: Optimierungsreihenfolge
CDN + Kompression aktivieren. Explizite Bilddimensionen. Self-hosted Fonts mit font-display: swap. Ungenutztes CSS/JS entfernen. Das allein bringt die meisten Seiten in den „Gut"-Bereich.
Bilder zu WebP/AVIF konvertieren. Responsives srcset generieren. LCP-Bild preloaden. Below-fold-Bilder lazy laden. Diese Phase spart typischerweise 1–3 Sekunden beim LCP.
Drittanbieter-Skripte auditieren. Schwere Bibliotheken durch leichtere Alternativen ersetzen. Astro Islands mit client:visible für verzögerte Hydration. JS-Budgets setzen und durchsetzen.
Lighthouse CI in Deployment-Pipeline einrichten. CrUX-Daten monatlich überwachen. Performance-Budgets erstellen. Regressionen erkennen, bevor sie Nutzer erreichen.
Wie CSS Custom Properties und Design Tokens dein Styling wartbar und performant halten, erfährst du im Design-Tokens-Guide.