Next.js Core Web Vitals in der Praxis: LCP, FCP und CLS im Griff

Letzten Monat habe ich die Performance-Optimierung eines E-Commerce-Projekts übernommen. Der Lighthouse-Score blieb bei etwa 65 Punkten, LCP (Largest Contentful Paint) schwankte um 3,5 Sekunden. Der Auftraggeber berichtete von hoher Absprungrate und stagnierender Conversion-Rate.
Zwei Wochen systematischer Core Web Vitals-Optimierung brachten den Lighthouse-Score auf 95 Punkte und senkten LCP auf 1,2 Sekunden. Noch wichtiger: Die Conversion-Rate stieg um 28 %. Performance-Optimierung ist nicht nur eine technische Kennzahl – sie schafft echten Geschäftswert.
Laut aktuellen Daten aus 2025 erfüllen nur 47 % der Websites Googles Core Web Vitals-Standards. Schlechte Performance kostet 8–35 % Umsatz, Ranking und Conversions. Das ist keine Panikmache, sondern die realen wirtschaftlichen Folgen.
In diesem Artikel teile ich Praxiserfahrungen aus der Next.js-Performance-Optimierung. Sie lernen:
- Konkrete Optimierungsmethoden für die drei Kernkennzahlen LCP, INP und CLS
- 10+ direkt kopierbare Codebeispiele
- 5 typische Performance-Fallstricke
Core Web Vitals 2025 – was sich geändert hat
Bevor Sie optimieren, sollten Sie die aktuellen Regeln kennen. Viele Artikel sprechen noch von FID (First Input Delay) – dieser Wert wurde jedoch im März 2024 abgeschafft.
Die drei aktuellen Kernkennzahlen
Google konzentriert sich jetzt auf diese drei Metriken:
-
LCP (Largest Contentful Paint) – Largest Contentful Paint
- Ziel: ≤ 2,5 s
- Misst die Ladeperformance
- Trägt 25 % zum Lighthouse-Score bei
-
INP (Interaction to Next Paint) – Interaction to Next Paint
- Ziel: ≤ 200 ms
- Misst die Reaktionsgeschwindigkeit bei Interaktionen
- Seit März 2024 Ersatz für FID
-
CLS (Cumulative Layout Shift) – Cumulative Layout Shift
- Ziel: < 0,1
- Misst visuelle Stabilität
FCP (First Contentful Paint) ist keine Kernkennzahl mehr, bleibt aber wichtig – er prägt den ersten Eindruck.
Warum diese Kennzahlen wichtig sind
Kennen Sie das? Sie öffnen eine Website, wollen auf einen Button klicken – und plötzlich springt die Seite, Sie treffen woanders. Das ist schlechtes CLS.
Oder Sie starren auf einen weißen Bildschirm und denken: „Ist die Verbindung abgebrochen?” Das ist zu langsames LCP.
Laut Chrome-Team liegt der durchschnittliche LCP-Wert top-performanter Websites bei etwa 1.220 ms. Liegt Ihr LCP über 2,5 Sekunden, hängen Sie hinter den meisten Wettbewerbern zurück.
LCP-Optimierung – das größte Inhaltselement schnell anzeigen
LCP war die Kennzahl, in die ich am meisten Zeit investiert habe – und der Effekt war am deutlichsten. Im Folgenden Schritt für Schritt.
Schritt 1: Ihr LCP-Element identifizieren
Vor der Optimierung müssen Sie wissen, welches Element LCP ist. Typischerweise:
- Hero-Bild im Above-the-Fold-Bereich
- Video-Poster
- Große Überschrift oder Textblock
Schnelle Methode:
- Chrome DevTools öffnen (F12)
Ctrl+Shift+Pdrücken (Mac:Cmd+Shift+P)- „Show Rendering” eingeben
- „Core Web Vitals” aktivieren
- Seite neu laden – oben rechts erscheint das LCP-Element
Beim E-Commerce-Projekt war das LCP-Element das Hero-Bild auf der Startseite – ein 2 MB großes JPG. Das war das Problem.
Bildoptimierung: next/image richtig einsetzen
Viele glauben, mit der Next.js Image-Komponente sei alles erledigt. Das stimmt nicht – ich dachte anfangs genauso, LCP blieb trotzdem langsam.
Priorität ist entscheidend
Für LCP-Bilder müssen Sie dem Browser signalisieren: „Dieses Bild ist wichtig, bitte zuerst laden!” Next.js bietet zwei Wege:
Next.js 13–15 (weit verbreitet):
import Image from 'next/image';
export default function Hero() {
return (
<Image
src="/hero-image.jpg"
width={1200}
height={630}
priority // Wichtig: Browser soll zuerst laden
fetchPriority="high" // Zusätzliche Absicherung
alt="Produkt-Hero"
/>
);
}
Next.js 16+ (neueste Version):
Next.js 16 hat priority abgeschafft und nutzt stattdessen:
<Image
src="/hero-image.jpg"
width={1200}
height={630}
loading="eager" // Sofort laden, kein Lazy Loading
fetchPriority="high" // Hohe Priorität
alt="Produkt-Hero"
/>
Warum zwei Attribute? priority fügt automatisch Preload-Tags hinzu, fetchPriority signalisiert die Wichtigkeit der Ressource. Beides zusammen wirkt am besten.
Typische Fehler im Vergleich:
// ❌ Falsch: wird lazy geladen, LCP langsam
<Image
src="/hero-image.jpg"
width={1200}
height={630}
alt="Produkt-Hero"
/>
// ❌ Falsch: keine Größenangabe
<Image
src="/hero-image.jpg"
priority
alt="Produkt-Hero"
/>
Warum Größenangaben wichtig sind
Die Next.js Image-Komponente verlangt width und height – nicht aus Schik, sondern um CLS (Layout-Verschiebungen) zu vermeiden.
Bei responsivem Layout:
// Mit fill für responsives Layout
<div style={{ position: 'relative', width: '100%', aspectRatio: '16/9' }}>
<Image
src="/hero-image.jpg"
fill
priority
style={{ objectFit: 'cover' }}
alt="Produkt-Hero"
/>
</div>
Der Eltern-Container braucht eine feste Größe oder aspect-ratio, sonst weiß das Bild nicht, wie groß es rendern soll.
Font-Optimierung: next/font mit automatischem Inline
Langsame Font-Ladezeiten bremsen LCP – besonders bei großen Schriftdateien. Next.js 13 führte next/font ein.
Google Fonts:
// app/layout.jsx
import { Inter, Noto_Sans_SC } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap', // Font-Flackern vermeiden
});
const notoSansSC = Noto_Sans_SC({
subsets: ['chinese-simplified'],
weight: ['400', '700'],
display: 'swap',
});
export default function RootLayout({ children }) {
return (
<html lang="zh-CN" className={`${inter.className} ${notoSansSC.className}`}>
<body>{children}</body>
</html>
);
}
Eigene Fonts:
import localFont from 'next/font/local';
const myFont = localFont({
src: './my-font.woff2',
display: 'swap',
});
export default function Layout({ children }) {
return <div className={myFont.className}>{children}</div>;
}
next/font übernimmt automatisch:
- Font-CSS inline einbinden, weniger Netzwerk-Requests
- Subsetting – nur benötigte Zeichen laden
- Font-Dateien vorladen
- Layout-Verschiebungen eliminieren
Nach dem Wechsel zu next/font sank LCP im Projekt um weitere 0,3 Sekunden.
Server-Antwortzeit reduzieren
Bilder und Fonts optimiert, LCP immer noch langsam? Dann liegt es oft an der Server-Antwortzeit (TTFB).
Statische Generierung bevorzugen
Next.js bietet mehrere Rendering-Modi – Performance von gut nach schlecht:
- SSG (Static Site Generation) – HTML beim Build, am schnellsten
- ISR (Incremental Static Regeneration) – statische Seiten bei Bedarf neu generieren
- SSR (Server-Side Rendering) – HTML pro Request, langsamer
- CSR (Client-Side Rendering) – Client-Rendering, LCP am langsamsten
SSG nutzen, wo möglich:
// app/blog/[slug]/page.jsx
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return <article>{/* ... */}</article>;
}
Bei Echtzeit-Daten ISR nutzen:
// app/products/[id]/page.jsx
export const revalidate = 3600; // Stündlich neu generieren
export default async function ProductPage({ params }) {
const product = await getProduct(params.id);
return <div>{/* ... */}</div>;
}
CDN und Edge Network
Bei Vercel-Deployment werden statische Assets automatisch global über das Edge Network ausgeliefert – TTFB sinkt deutlich.
Auf anderen Plattformen Cloudflare, AWS CloudFront o. Ä. als CDN einsetzen.
Schwere Berechnungen nicht im Server-Request
Den Fehler habe ich selbst gemacht: komplexe Datenverarbeitung im Server-Request, 500 ms pro Render – LCP leidet.
Anti-Beispiel:
// ❌ Falsch: Berechnung bei jedem Request
export default async function Page() {
const data = await fetchData();
const processed = heavyProcessing(data); // 500 ms
return <div>{processed}</div>;
}
Richtig:
Ergebnisse cachen oder beim Build vorberechnen:
// ✅ Richtig: beim Build berechnen
export async function generateStaticParams() {
const data = await fetchData();
const processed = heavyProcessing(data);
// Ergebnis in DB oder Datei speichern
await saveProcessedData(processed);
}
export default async function Page() {
const processed = await getProcessedData(); // direkt lesen
return <div>{processed}</div>;
}
CLS-Optimierung – Layout-Sprünge beseitigen
CLS (Cumulative Layout Shift) ist oft am frustrierendsten – die Seite springt plötzlich. Das Problem hat mich eine Weile beschäftigt.
Größen für Bilder und Medien reservieren
Häufigste CLS-Ursache: Bilder laden und verschieben das Layout. Lösung: Größe vorab angeben.
Next.js Image erledigt das automatisch:
// ✅ Richtig: width/height gesetzt, kein CLS
<Image
src="/product.jpg"
width={400}
height={300}
alt="Produktbild"
/>
Dynamische Bilder aus dem CMS?
// ✅ Richtig: aspect-ratio reserviert Platz
<div style={{ position: 'relative', width: '100%', aspectRatio: '4/3' }}>
<Image
src={dynamicImageUrl}
fill
style={{ objectFit: 'cover' }}
alt="Dynamisches Bild"
/>
</div>
Videos ebenso:
<video
width="1280"
height="720"
poster="/video-poster.jpg"
controls
>
<source src="/video.mp4" type="video/mp4" />
</video>
Platz für dynamische Inhalte reservieren
Werbung, Banner, Embeds (z. B. Twitter-Karten) verursachen CLS. Platz im Voraus reservieren.
Werbe-Container:
// ✅ Richtig: Werbehöhe reserviert
<div
style={{
minHeight: '250px', // Standardhöhe Google AdSense
backgroundColor: '#f0f0f0' // Platzhalter-Hintergrund
}}
>
{/* Werbe-Skript */}
<ins className="adsbygoogle" />
</div>
Benachrichtigungsleiste:
// ❌ Falsch: plötzliches Erscheinen, Seite rutscht nach unten
{showBanner && <NotificationBanner />}
// ✅ Richtig: Platz von Anfang an reserviert
<div style={{ minHeight: '60px' }}>
{showBanner ? <NotificationBanner /> : <div style={{ height: '60px' }} />}
</div>
Skeleton-Screens:
Für dynamisch geladene Inhalte Skeleton-Platzhalter nutzen:
function ProductList() {
const { data, isLoading } = useQuery('products', fetchProducts);
if (isLoading) {
return (
<div className="grid grid-cols-3 gap-4">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="skeleton" style={{ height: '300px' }} />
))}
</div>
);
}
return (
<div className="grid grid-cols-3 gap-4">
{data.map(product => <ProductCard key={product.id} {...product} />)}
</div>
);
}
Font-Lade-Optimierung
Fonts verursachen CLS – sichtbar als Text-Flackern oder Größenwechsel.
next/font löst das automatisch; manuell geht es so:
const inter = Inter({
subsets: ['latin'],
display: 'optional', // Wenn Font nicht rechtzeitig da: Systemfont nutzen
adjustFontFallback: true, // Fallback-Größe anpassen, weniger Sprung
});
Optionen für display:
swap: Fallback zuerst, dann Wechsel (kann CLS verursachen)optional: Font nicht rechtzeitig geladen → Systemfont (empfohlen)block: Text kurz ausblenden (nicht empfohlen)fallback: Kompromiss zwischen swap und optional
Ich empfehle optional – eventuell ohne Custom-Font, dafür stabilere UX.
JavaScript-gesteuertes responsives Layout vermeiden
Der häufigste CLS-Fallstrick 2025! Viele Next.js-Projekte machen denselben Fehler.
Typischer Fehlercode:
// ❌ Falsch: verursacht starkes CLS
import { useMediaQuery } from '@/hooks/useMediaQuery';
export default function ResponsiveLayout() {
const isMobile = useMediaQuery('(max-width: 768px)');
return (
<div>
{isMobile ? (
<MobileNav />
) : (
<DesktopNav />
)}
</div>
);
}
Warum CLS?
- Beim ersten Render ist JavaScript noch nicht gelaufen –
isMobileistundefinedoder Default - Nach JS-Ausführung liefert
useMediaQueryden echten Wert - Re-Render, Layout springt
Bei SSR noch schlimmer – der Server kennt die Bildschirmbreite nicht.
Richtig: CSS Media Queries
// ✅ Richtig: CSS steuert Sichtbarkeit, kein CLS
export default function ResponsiveLayout() {
return (
<>
<nav className="mobile-nav md:hidden">
<MobileNav />
</nav>
<nav className="desktop-nav hidden md:block">
<DesktopNav />
</nav>
</>
);
}
Oder mit CSS-in-JS:
export default function ResponsiveLayout() {
return (
<div className="responsive-container">
<MobileNav />
<DesktopNav />
<style jsx>{`
.responsive-container > :global(.mobile-nav) {
display: block;
}
.responsive-container > :global(.desktop-nav) {
display: none;
}
@media (min-width: 768px) {
.responsive-container > :global(.mobile-nav) {
display: none;
}
.responsive-container > :global(.desktop-nav) {
display: block;
}
}
`}</style>
</div>
);
}
Brauchen Sie JavaScript für unterschiedliche Daten (nicht nur Layout), User-Agent serverseitig auswerten:
// app/page.jsx
import { headers } from 'next/headers';
export default async function Page() {
const headersList = headers();
const userAgent = headersList.get('user-agent') || '';
const isMobile = /mobile/i.test(userAgent);
return (
<div>
{isMobile ? <MobileView /> : <DesktopView />}
</div>
);
}
Server und Client rendern identisch – kein CLS.
FCP-Optimierung – First Contentful Paint beschleunigen
FCP ist keine Kernkennzahl, prägt aber den ersten Eindruck. Lange weiße Bildschirme → Nutzer schließen die Seite.
Kritische Ressourcen optimieren
Langsames FCP entsteht oft durch render-blockierende Ressourcen. Chrome DevTools Coverage zeigt ungenutztes CSS und JavaScript.
Kritisches CSS inline:
Next.js optimiert CSS automatisch; manuell geht es so:
// app/layout.jsx
export default function RootLayout({ children }) {
return (
<html>
<head>
<style
dangerouslySetInnerHTML={{
__html: `
/* Kritisches CSS: Above-the-Fold */
body { margin: 0; font-family: system-ui; }
.hero { height: 100vh; }
`,
}}
/>
</head>
<body>{children}</body>
</html>
);
}
Nicht-kritisches CSS verzögert laden:
Styles für Modals, Accordions etc. können später geladen werden:
// CSS dynamisch in Komponente importieren
import dynamic from 'next/dynamic';
const Modal = dynamic(() => import('./Modal'), {
loading: () => <p>Loading...</p>,
});
Drittanbieter-Skripte steuern
Google Analytics, Werbung, Social Plugins – Performance-Killer. Viele langsame FCP-Werte kommen daher.
next/script nutzen:
Next.js bietet die Script-Komponente mit Lade-Strategien:
import Script from 'next/script';
export default function Layout({ children }) {
return (
<>
{children}
{/* Google Analytics: nach Interaktivität laden */}
<Script
src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
strategy="lazyOnload"
/>
<Script id="ga-init" strategy="lazyOnload">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
`}
</Script>
{/* Facebook Pixel: verzögert laden */}
<Script
src="https://connect.facebook.net/en_US/fbevents.js"
strategy="lazyOnload"
/>
</>
);
}
strategy-Optionen:
beforeInteractive: vor Interaktivität (kritische Skripte)afterInteractive: nach Interaktivität (Standard)lazyOnload: bei Idle (Analytics und Werbung)worker: im Web Worker (experimentell)
Alle nicht essentiellen Drittanbieter-Skripte auf lazyOnload umgestellt – FCP um 0,8 Sekunden verbessert.
Code-Splitting und Lazy Loading
Next.js splittet automatisch; manchmal braucht es manuelle Optimierung.
Komponenten lazy laden:
import dynamic from 'next/dynamic';
// Kommentare lazy laden
const Comments = dynamic(() => import('./Comments'), {
loading: () => <div>Kommentare werden geladen...</div>,
ssr: false, // kein SSR
});
export default function BlogPost({ post }) {
return (
<article>
<h1>{post.title}</h1>
<div>{post.content}</div>
{/* Kommentare erst beim Scrollen laden */}
<Comments postId={post.id} />
</article>
);
}
Große Bibliotheken lazy laden:
Chart.js, Rich-Text-Editoren etc. nur bei Bedarf laden.
Beispiel: Chart.js – 800 KB sparen
Ein Projekt importierte Chart.js global, nutzte es aber nur auf dem Dashboard – jede Seite lud 800 KB.
Vorher:
// ❌ Falsch: globaler Import, jede Seite lädt mit
import { Chart } from 'chart.js';
export default function Dashboard() {
return <canvas ref={chartRef} />;
}
Nachher:
// ✅ Richtig: nur bei Bedarf laden
import dynamic from 'next/dynamic';
const ChartComponent = dynamic(() => import('./ChartComponent'), {
loading: () => <div>Diagramm wird geladen...</div>,
ssr: false,
});
export default function Dashboard() {
return <ChartComponent />;
}
// ChartComponent.jsx
import { Chart } from 'chart.js';
export default function ChartComponent() {
return <canvas ref={chartRef} />;
}
Nur Dashboard-Besucher laden Chart.js – andere Seiten unberührt.
Bilder lazy laden:
Außer LCP-Bildern sollten Bilder lazy geladen werden:
<Image
src="/feature-image.jpg"
width={600}
height={400}
loading="lazy" // Standard, kann weggelassen werden
alt="Feature-Übersicht"
/>
Monitoring und kontinuierliche Optimierung
Optimierung ist kein Einmal-Job – Performance braucht regelmäßige Kontrolle.
Lighthouse CI automatisieren
Manuelles Lighthouse ist zeitaufwändig und leicht vergessen. Besser: in CI/CD integrieren.
Lighthouse CI installieren:
npm install -D @lhci/cli
Konfiguration lighthouserc.js:
module.exports = {
ci: {
collect: {
url: ['http://localhost:3000/', 'http://localhost:3000/products'],
numberOfRuns: 3, // 3 Durchläufe, Mittelwert
},
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.9 }], // Performance ≥ 90
'first-contentful-paint': ['error', { maxNumericValue: 2000 }], // FCP ≤ 2 s
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }], // LCP ≤ 2,5 s
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }], // CLS < 0,1
},
},
upload: {
target: 'temporary-public-storage',
},
},
};
GitHub Actions:
# .github/workflows/lighthouse.yml
name: Lighthouse CI
on: [push]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm install
- run: npm run build
- run: npm run start &
- run: npx @lhci/cli autorun
Bei jedem Push läuft Lighthouse automatisch. Performance-Rückschritt → CI schlägt fehl.
Real User Monitoring (RUM)
Lighthouse misst im Labor – echte Nutzer erleben oft etwas anderes. Core Web Vitals aus dem Feld sammeln.
Vercel Analytics:
Bei Vercel-Deployment mit einem Klick aktivieren:
// app/layout.jsx
import { Analytics } from '@vercel/analytics/react';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Analytics />
</body>
</html>
);
}
web-vitals-Bibliothek:
Ohne Vercel Googles web-vitals nutzen:
npm install web-vitals
// app/layout.jsx
'use client';
import { useEffect } from 'react';
import { onLCP, onFID, onCLS, onINP } from 'web-vitals';
function sendToAnalytics(metric) {
// An Analytics-Dienst senden
fetch('/api/analytics', {
method: 'POST',
body: JSON.stringify(metric),
});
}
export default function Analytics() {
useEffect(() => {
onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
}, []);
return null;
}
Google Search Console:
Der Core Web Vitals-Bericht zeigt reale Nutzerdaten und markiert Seiten mit Handlungsbedarf.
Typische Fallstricke und Lösungen
Fünf häufige Fehler:
Fallstrick 1: Zu viel Client-JavaScript
Viele nutzen React für alles – die ganze Seite hängt an JavaScript. Lädt JS langsam oder gar nicht → weißer Bildschirm.
Lösung:
- Server Components bevorzugen (Next.js 13+ Standard)
'use client'nur wo nötig- Progressive Enhancement: Basisfunktion zuerst, Interaktivität danach
Fallstrick 2: Mobile Performance ignorieren
Schnell am Desktop heißt nicht schnell am Handy – schwächere CPU, langsamere Netze.
Lösung:
- Lighthouse im Modus „Mobile” testen
- Netzwerk drosseln (Chrome DevTools → Network → Throttling)
- CPU drosseln (Chrome DevTools → Performance → CPU)
Fallstrick 3: Drittanbieter-Skripte unoptimiert
Google Analytics, Facebook Pixel, Intercom, Hotjar – jedes Skript kostet Performance.
Lösung:
- Alles mit
next/scriptundstrategy="lazyOnload" - Regelmäßig prüfen: Was ist wirklich nötig?
- Server-seitiges Tracking statt Client-Tracking erwägen
Fallstrick 4: Falsches Bildformat
Noch PNG und JPG ohne moderne Alternativen? WebP und AVIF sparen 30–50 % Volumen.
Lösung:
Next.js Image konvertiert automatisch – Server muss es unterstützen:
// next.config.js
module.exports = {
images: {
formats: ['image/avif', 'image/webp'], // Moderne Formate bevorzugen
},
};
Fallstrick 5: Server-Performance vernachlässigen
Perfektes Frontend nützt wenig, wenn der Server langsam antwortet.
Lösung:
- Datenbankabfragen optimieren (Indizes, N+1 vermeiden)
- Caching (Redis, CDN)
- Server-Performance überwachen (APM: New Relic, Datadog)
Zusammenfassung
LCP – das Wichtigste:
priorityundfetchPriority="high"für LCP-Bildernext/fontfür Font-Ladezeiten- SSG und ISR bevorzugen, Server-Berechnung reduzieren
- CDN für niedrigeren TTFB
CLS – das Wichtigste:
- Breite und Höhe für alle Medien
- Platz für dynamische Inhalte (Werbung, Banner)
- Kein responsives Layout per JavaScript-Hooks
next/fontgegen Font-Sprünge
FCP – das Wichtigste:
- Nicht-kritische Ressourcen verzögert laden
- Drittanbieter-Skripte mit
next/scriptundlazyOnload - Große Bibliotheken und Below-the-Fold-Komponenten lazy laden
Kontinuierlich:
- Lighthouse CI automatisieren
- Echte Nutzerdaten (RUM) sammeln
- Code regelmäßig prüfen und aufräumen
Performance-Optimierung ist ein Zyklus: messen → optimieren → erneut messen. Nicht alles auf einmal – kontinuierlich verbessern.
Als der Lighthouse-Score endlich über 90 lag, war die Freude groß. Die Conversion-Steigerung zeigte: Die Arbeit hat sich gelohnt.
Aktionsliste
So können Sie starten:
-
Sofort:
- Lighthouse für Ihr Next.js-Projekt ausführen
- LCP-Element finden – ist
prioritygesetzt? - Code mit
useMediaQueryund ähnlichem CLS-Risiko prüfen
-
Diese Woche:
- LCP-Bilder optimieren (priority + fetchPriority)
- Fonts auf
next/fontumstellen - Platzhalter für dynamische Inhalte
-
Nächste Woche:
- Drittanbieter-Skripte auf
lazyOnload - Große Bibliotheken und Below-the-Fold-Komponenten lazy laden
- Lighthouse CI einrichten
- Drittanbieter-Skripte auf
-
Dauerhaft:
- Lighthouse-Score monatlich prüfen
- Core Web Vitals in der Google Search Console beobachten
- Performance-Rückschritte zeitnah beheben
Performance-Optimierung ist kein Einmal-Projekt, sondern ein laufender Prozess. Viel Erfolg!
Next.js Core Web Vitals – vollständiger Optimierungsablauf
LCP, INP und CLS optimieren und Lighthouse-Score auf 90+ bringen
⏱️ Estimated time: 8 hr
- 1
Step 1: LCP (Largest Contentful Paint) optimieren
Ziel: ≤ 2,5 s
Optimierungsmethoden:
• next/image für Bildoptimierung (automatische WebP/AVIF-Konvertierung)
• priority für kritische Above-the-Fold-Bilder
• Kritische Ressourcen vorladen (<link rel="preload">)
• Server-Antwortzeit optimieren (CDN, Edge Functions)
• Render-blockierende Ressourcen reduzieren (nicht-kritisches CSS/JS verzögert laden)
• React Server Components zur Reduzierung von Client-JS
Prüftools:
• Lighthouse Performance-Bericht
• Chrome DevTools Performance-Panel
• WebPageTest (Online-Test) - 2
Step 2: INP (Interaction to Next Paint) optimieren
Ziel: ≤ 200 ms
Optimierungsmethoden:
• JavaScript-Ausführungszeit reduzieren (Code-Splitting, Lazy Loading)
• React Server Components zur Reduzierung von Client-JS
• Event-Handling optimieren (Debouncing, Throttling, Event-Delegation)
• Lange Tasks vermeiden (Web Workers nutzen)
• Drittanbieter-Skripte optimieren (verzögert laden, async/defer)
• Suspense und Streaming-Rendering nutzen
Prüftools:
• Chrome DevTools Performance-Panel
• Web Vitals Chrome-Erweiterung
• Real User Monitoring (RUM)-Tools - 3
Step 3: CLS (Cumulative Layout Shift) optimieren
Ziel: ≤ 0,1
Optimierungsmethoden:
• Breite und Höhe für Bilder und Videos setzen (oder aspect-ratio nutzen)
• Dynamisches Einfügen von Inhalten vermeiden (Platz reservieren)
• font-display: swap gegen Layout-Sprünge durch Fonts
• Platz für Werbung reservieren (kein Verschieben nach dem Laden)
• CSS Grid/Flexbox statt absoluter Positionierung
• Keine neuen Inhalte über bestehendem Content einfügen
Prüftools:
• Lighthouse CLS-Bericht
• Layout-Shift-Einträge im Chrome DevTools Performance-Panel
• WebPageTest CLS-Visualisierung - 4
Step 4: Next.js Performance-Features nutzen
Next.js Optimierungstipps:
• Image-Komponente für automatische Bildoptimierung
• Font Optimization für automatische Font-Optimierung
• React Server Components zur Reduzierung von Client-JS
• Streaming SSR für schnelleren First Screen
• Dynamic Imports für Code-Splitting
• next/dynamic für verzögertes Laden von Komponenten
Konfiguration prüfen:
• Performance-relevante Einstellungen in next.config.js
• Bundle-Größe prüfen (npm run build) - 5
Step 5: Monitoring und kontinuierliche Optimierung
Monitoring-Tools:
• Google Search Console Core Web Vitals-Bericht
• Vercel Analytics (bei Vercel-Deployment)
• Web Vitals Chrome-Erweiterung
• Real User Monitoring (RUM)-Tools
Kontinuierliche Optimierung:
• Lighthouse-Score monatlich prüfen
• Core Web Vitals-Bericht in der Search Console beobachten
• Performance-Rückschritte zeitnah beheben
• A/B-Tests für Optimierungseffekte
FAQ
Was sind die drei Kennzahlen der Core Web Vitals?
Wie optimiere ich LCP?
Was ist der Unterschied zwischen INP und FID?
Wie vermeide ich CLS (Layout-Verschiebungen)?
Wie lange dauert es, bis Optimierungen wirken?
Welche Next.js-Features helfen bei der Performance?
Wie überwache ich Core Web Vitals?
13 Min. Lesezeit · Veröffentlicht am: 19. Dez. 2025 · Aktualisiert am: 14. Juli 2026
Next.js Komplettleitfaden
Wenn du über die Suche hier gelandet bist, kommst du am schnellsten weiter, indem du zum vorherigen oder nächsten Beitrag dieser Serie springst.
Vorheriger
Next.js Bildoptimierung: Der vollständige Leitfaden zur Image-Komponente
Next.js Image-Komponente im Detail: langsame Bilder, Remote-Host-Fehler und Layout-Verschiebung lösen. Next.js 14/15, Praxiscode und Performance-Tipps – oft 60–80 % weniger Bildvolumen.
Teil 26 von 51
Nächster
Next.js SEO: Vollständiger Leitfaden – Metadata API und strukturierte Daten in der Praxis
Vollständiger Leitfaden zur SEO-Konfiguration mit der Next.js 15 Metadata API: strukturierte Daten, Open Graph, Twitter Cards – mit Praxiscode und typischen Fallstricken, damit Ihr Traffic wächst
Teil 28 von 51
Ähnliche Beiträge
Next.js App Router Einstieg: Kernkonzepte und Grundlagen im Überblick

Next.js App Router Einstieg: Kernkonzepte und Grundlagen im Überblick
Next.js 15 in der Praxis: Wie ich an einem Wochenende ein produktionsreifes Blog-System aufgebaut habe


Kommentare
Melde dich mit GitHub an, um einen Kommentar zu hinterlassen