Verbessern Sie Core Web Vitals in Next.js, indem Sie wichtige Inhalte früh liefern, Browser-JavaScript begrenzen und Platz für später eintreffende Elemente reservieren. Next.js bietet dafür nützliche Bausteine. Renderingstrategie und Komponentengrenzen bestimmen jedoch weiterhin, wie viel Arbeit das Gerät eines Besuchers leisten muss. Diagnostizieren Sie zunächst die langsame Metrik, bevor Sie die Framework-Konfiguration ändern.
Die Beispiele beziehen sich auf Next.js 16 mit App Router und wurden mit der als v16.4.2 ausgewiesenen Dokumentation abgeglichen. Sie zeigen Implementierungsmuster, keine Benchmark-Ergebnisse. Anwendungen mit Pages Router sowie React-Anwendungen ohne Next.js benötigen andere Integrationspunkte, obwohl die Browserprobleme vergleichbar bleiben.
Beginnen Sie mit Route und Metrik
Wählen Sie eine reale Route mit einem messbaren Problem, nicht die am einfachsten zu optimierende Seite. Halten Sie Geräteklasse, Navigationsart, Deployment und Benutzerzustand fest. Ein gecachter öffentlicher Artikel, ein angemeldetes Dashboard und eine Produktseite mit personalisierten Empfehlungen haben unterschiedliche kritische Pfade.
LCP beschreibt, wann der größte berücksichtigte sichtbare Inhalt gezeichnet wird. Eine verzögerte Serverantwort, eine spät gestartete Bildanfrage oder Arbeit im Hauptthread können diesen Zeitpunkt verschieben. INP betrifft die Reaktionsfähigkeit während des gesamten Besuchs. Hydration, Filter-Handler und Rendering nach einer Zustandsänderung können zu verschiedenen Zeitpunkten beitragen. CLS erfasst unerwartete Verschiebungen, auch nach dem ersten sichtbaren Seitenaufbau.
Identifizieren Sie die betroffene Nutzergruppe mit Felddaten und erklären Sie die Verzögerung anhand einer Browseraufzeichnung. Ein normaler Lighthouse-Navigationstest belegt keinen INP-Wert aus dem Produktivbetrieb. Umgekehrt beweist ein schneller Klick auf dem Entwicklerlaptop keine gute Reaktionsfähigkeit für reale Besucher. Der Leitfaden zur INP-Diagnose trennt Eingabe-, Verarbeitungs- und Darstellungsverzögerungen.
Notieren Sie vor Änderungen Route, beobachtetes LCP-Element, relevante lange Aufgaben, Ursachen von Layoutverschiebungen und die dort geladenen Skripte. So wird aus einem allgemeinen Vorhaben eine überprüfbare Annahme. Beginnt das Hauptbild zu spät, sollte die erste Änderung dessen Erkennung oder Priorisierung betreffen, nicht eine unabhängige Paketbereinigung.
Richten Sie das Rendering am tatsächlichen Inhaltsbedarf aus
Statische Generierung, Rendering pro Anfrage, Streaming und clientseitiges Rendering beschreiben verschiedene Teile der Auslieferung. Server Components beschreiben dagegen den Ausführungsort des Komponentencodes. Eine Server Component kann sowohl zu einer statischen Route als auch zu anfrageabhängiger Arbeit gehören. Ihr Name legt keine Cache-Strategie fest.
Diese Abwägungen sind praktisch relevant:
| Ansatz | Möglicher Vorteil | Zu prüfendes Risiko |
|---|---|---|
| Statisches oder gecachtes HTML | Früher Inhalt ohne wiederholte Ursprungsarbeit | Veraltete Inhalte bei falscher Invalidierung |
| Serverseitiges Rendering pro Anfrage | Aktuelles oder personalisiertes HTML | Langsame Datenabhängigkeiten verzögern die Antwort |
| Streaming | Nützliche Abschnitte erscheinen vor langsameren | Der LCP-Inhalt wartet weiterhin hinter einer Grenze |
| Clientseitig gerenderter Inhalt | Interaktive Ansichten laden Daten bei Bedarf | Skript- und Datenketten vor nutzbarem Inhalt |
Wählen Sie anfrageabhängige Arbeit nicht allein deshalb, weil die Anwendung React verwendet. Öffentliche Dokumentation, die sich nur bei Veröffentlichungen ändert, lässt sich häufig vorher erzeugen. Personalisierung kann dynamische Arbeit verlangen, doch umgebende Navigation und beschreibender Text müssen nicht auf sämtliche personalisierten Abhängigkeiten warten.
Streaming wird leicht falsch beurteilt. Ein früher ausgeliefertes Ladegerüst kann den ersten Eindruck verbessern, ohne das endgültige LCP-Element vorzuziehen. Prüfen Sie den tatsächlichen Eingang des Inhalts und nicht nur das erste Dokumentbyte. Platzhalter und Ersatz sollten vergleichbare Abmessungen haben, damit die schrittweise Auslieferung keine Sprünge verursacht.
Das Cache-Verhalten hängt von Next.js-Version und aktivierten Funktionen ab. Prüfen Sie die erzeugte Route und das Deployment, statt Annahmen älterer Versionen zu übernehmen. Eine aufgewärmte Entwicklungsumgebung sagt nichts Verlässliches über eine kalte Produktionsanfrage aus. Testen Sie direkte Dokumentaufrufe und Client-Navigationen, da dabei unterschiedliche Ressourcen angefordert werden können.
Halten Sie Client-Grenzen überschaubar
Im App Router sind Seiten und Layouts standardmäßig Server Components. Verwenden Sie Client Components für Zustand, Ereignisbehandlung und Browser-APIs. Setzen Sie 'use client' an die kleinste sinnvolle interaktive Grenze, etwa einen Filter oder ein aufklappbares Steuerelement. Ein einzelner Button rechtfertigt nicht automatisch ein komplettes inhaltsreiches Client-Layout.
Die Grenze wirkt auf den importierten Modulgraphen. Eine aufwendige Bibliothek, die das Client-Modul importiert, kann im Browser-Bundle landen, obwohl der größte Teil der Seite statisch aussieht. Prüfen Sie die Importe des interaktiven Bausteins und übergeben Sie nur benötigte Daten. Große serialisierte Props verursachen Übertragungs- und Verarbeitungskosten, selbst wenn die Datentransformation auf dem Server stattfand.
Eine Client Component bedeutet nicht, dass ihr HTML ausschließlich im Client entsteht. Next.js kann ihre erste Ausgabe vorab rendern und anschließend im Browser hydrieren. Diese Unterscheidung ist wichtig, wenn eine Seite bereits vollständig aussieht, ihre Steuerelemente aber noch nicht reagieren. Das HTML ist angekommen, während JavaScript und Ereignisbehandlung noch vorbereitet werden.
Ermitteln Sie mit einer Analyse des Produktions-Bundles, warum eine Abhängigkeit eine Route erreicht. Prüfen Sie anschließend in einer Performance-Aufzeichnung, ob ihre Ausführung relevant ist. Komprimierte Dateigröße und CPU-Zeit beantworten unterschiedliche Fragen. Der Leitfaden zur JavaScript-Ausführungszeit hilft, wenn bessere Downloads lange Aufgaben nicht verkürzen.
Planen Sie die Ladung des tatsächlichen LCP-Bildes
Liefern Sie mit next/image Abmessungen und responsive Bildvarianten und beschreiben Sie die dargestellte Breite korrekt. Die intrinsischen Werte width und height reservieren das Seitenverhältnis; CSS steuert die Darstellung. Bei fill benötigt das Elternelement eine Positionierung sowie definierte Abmessungen oder ein Seitenverhältnis. Fehlende Geometrie kann eine Bildoptimierung in ein Layoutproblem verwandeln.
Dieses Beispiel für app/page.jsx setzt voraus, dass public/images/storefront.webp existiert und im ersten Sichtbereich das wichtige Bild ist:
// app/page.jsx
import Image from 'next/image';
export default function Page() {
return (
<main style={{ maxWidth: 960, margin: '0 auto' }}>
<h1>A guide to faster storefronts</h1>
<Image
src="/images/storefront.webp"
alt="A storefront with a wide display window"
width={1600}
height={900}
sizes="(max-width: 960px) 100vw, 960px"
loading="eager"
fetchPriority="high"
style={{ width: '100%', height: 'auto' }}
/>
</main>
);
}sizes entspricht dem Beispielcontainer, der bis maximal 960 CSS-Pixel die verfügbare Breite nutzt. Ändern Sie den Wert bei einem anderen Layout. Eine Karte in einem mehrspaltigen Raster sollte nicht aus Bequemlichkeit die gesamte Fensterbreite angeben. Prüfen Sie den ausgewählten Bildkandidaten im Netzwerkbereich bei typischen Fensterbreiten und Pixeldichten.
Seit Next.js 16 ist priority zugunsten von preload veraltet. Daraus folgt nicht, dass jeder bisherige Einsatz von priority eine bedingungslose Vorabladung werden sollte. Die Referenz der Image-Komponente bevorzugt meistens sofortiges Laden oder eine hohe Abrufpriorität und rät davon ab, preload mit loading oder fetchPriority zu kombinieren.
Das Beispiel kombiniert daher sofortiges Laden mit einem Prioritätshinweis, ohne preload. Eine Vorabladung ist eine eigene Option, wenn ein bekanntes kritisches Bild früher entdeckt werden muss. Laden Sie nicht mehrere konkurrierende Mobil- und Desktop-Hauptbilder vorab, ohne den tatsächlich genutzten Kandidaten zu verstehen. Unwichtige Bilder außerhalb des Sichtbereichs bleiben verzögert geladen. Prüfen Sie nach der Änderung das reale LCP-Element erneut.
Kontrollieren Sie auch die Bildauslieferung. Entfernte Quellen benötigen passende remotePatterns; der Standardoptimierer erfordert eine kompatible Laufzeitumgebung. Ein statischer Export braucht eine ausdrückliche Strategie, etwa einen eigenen Loader oder bereits optimierte Dateien. Der Leitfaden zur Bildoptimierung behandelt Format, Abmessungen und Qualität jenseits der Komponente.
Entscheiden Sie über Schriften und Layoutstabilität gemeinsam
next/font kann Schriftdateien aus dem Deployment der Anwendung ausliefern. Bei next/font/google muss der Browser die Schrift nicht von Google anfordern. Bei next/font/local stammen die Dateien aus dem Projekt. Beide Optionen erfordern weiterhin Entscheidungen über Zeichenabdeckung, Schriftschnitte, Ersatzschriftmetriken und Datenmenge.
Dieses Root-Layout setzt eine lizenzierte lateinische Schrift unter app/fonts/body-latin.woff2 und die später gezeigte Messkomponente voraus:
// app/layout.jsx
import localFont from 'next/font/local';
import { WebVitals } from './web-vitals';
const bodyFont = localFont({
src: './fonts/body-latin.woff2',
display: 'swap',
});
export default function RootLayout({ children }) {
return (
<html lang="en" className={bodyFont.className}>
<body>
<WebVitals />
{children}
</body>
</html>
);
}Es handelt sich um ein englisches Layout, nicht um eine allgemeine Rezeptur für mehrsprachige Schriften. Koreanische und hebräische Seiten brauchen passende Zeichenabdeckung, Spracheinstellungen und gegebenenfalls Schreibrichtung. Eine ausschließlich lateinische Datei kann nicht alle Sprachen darstellen. Vermeiden Sie mehrere vollständige Schriftfamilien pro Route, wenn der Besucher nur eine Sprache verwendet.
display: 'swap' zeigt zunächst eine Ersatzschrift. Prüfen Sie, ob der Austausch Zeilenumbrüche, Navigationsbreite oder Kartenhöhe verändert. Fallback-Anpassungen des Frameworks helfen, beweisen aber keinen CLS-Wert von null für die gesamte Seite. Anzeigen, Einbettungen, nachgeladene Banner und gestreamte Abschnitte benötigen weiterhin reservierten Platz.
Vergleichen Sie die Seite bei langsamer Verbindung vor und nach dem Schriftladen. Achten Sie auf die LCP-bestimmende Überschrift, nicht nur auf einen Beispielabsatz. Ändert sich der Textumbruch, passen Sie Fallback und Layout an oder reduzieren Sie die Schriftabhängigkeit. Der Leitfaden zur Schriftoptimierung erklärt diese Untersuchung genauer.
Planen Sie Skripte, ohne Verschieben mit Entfernen zu verwechseln
next/script steuert den Ladezeitpunkt, macht die Ausführung aber nicht kostenlos. Wählen Sie den Geltungsbereich ebenso sorgfältig wie die Strategie. Ein Widget für eine einzelne Route sollte nicht automatisch im Root-Layout für alle Routen laufen.
Die Strategien haben unterschiedliche Aufgaben:
| Strategie | Vorgesehener Zeitpunkt | Praktische Einschränkung |
|---|---|---|
beforeInteractive |
Frühe kritische Skripte im Root-Layout | Nur für Code, den die gesamte Anwendung wirklich früh benötigt |
afterInteractive |
Nach einem Teil der Hydration; Standard | Kann mit frühen Interaktionen konkurrieren |
lazyOnload |
Während Browser-Leerlauf nach dem Laden | Spätere Ausführung kann Besucher weiterhin unterbrechen |
worker |
Experimentelles Laden in einem Worker | Laut geprüfter Dokumentation nicht im App Router unterstützt |
Späteres Laden kann den anfänglichen kritischen Pfad entlasten und zugleich eine spätere Interaktion verschlechtern. Stellen Sie die Aktion nach, die während der Widget-Initialisierung erfolgt. Laden Sie eine unwichtige Funktion gegebenenfalls erst auf Anforderung und zeigen Sie währenddessen eine erkennbare Rückmeldung. Einwilligungsanforderungen sind davon getrennt: Verzögerte Analyse-Skripte ergeben noch keine einwilligungsabhängige Integration.
Untersuchen Sie Hydration und anschließende Arbeit
Hydration ergänzt vorgerendertes HTML um React-Verhalten. Serverausgabe und erste Client-Ausgabe sollten übereinstimmen. Browserabhängiger Zustand, nicht deterministische Werte oder unterschiedliche Inhaltszweige können Abweichungen erzeugen. Alle Warnungen zu unterdrücken repariert das Auslieferungsmodell nicht.
Eine große Hydrationsaufgabe kann Eingaben verzögern, aber nicht jedes INP-Problem ist Hydration. Spätere Zustandsänderungen können große Teilbäume neu rendern, aufwendige Layoutberechnungen oder synchrone Berechnungen auslösen. Zeichnen Sie die langsame Aktion nach dem Stabilisieren der Seite und während des Ladens auf. Betrachten Sie das Intervall von der Eingabe bis zum nächsten gezeichneten Bild.
React-Werkzeuge zur Priorisierung können bestimmte Aktualisierungen steuern, verlagern jedoch beliebigen synchronen JavaScript-Code nicht aus dem Hauptthread. Entfernen Sie zunächst unnötige Berechnungen, begrenzen Sie den aktualisierten Teilbaum und vermeiden Sie wiederholte Layoutarbeit. Für erhebliche CPU-Arbeit kann eine geeignete Worker-Grenze sinnvoll sein. Prüfen Sie die Korrektheit: Ein schneller Filter mit vorübergehend falschem Ergebnis ist keine gelungene Optimierung.
Messen Sie einen Produktions-Build mit stabilem Callback
Im App Router wird useReportWebVitals aus next/web-vitals in einer kleinen Client Component verwendet. Eine stabile Callback-Referenz verhindert doppelte Meldungen, die durch neue Funktionsreferenzen bei erneutem Rendering entstehen können. Dieses Beispiel schreibt Beobachtungen in die Browserkonsole und überträgt keine Nutzerdaten:
// app/web-vitals.jsx
'use client';
import { useReportWebVitals } from 'next/web-vitals';
function reportMetric({ id, name, value, rating }) {
console.info('web-vital', { id, name, value, rating });
}
export function WebVitals() {
useReportWebVitals(reportMetric);
return null;
}Das Layout oben bindet die Komponente einmal ein. Beobachten Sie einen Produktions-Build, interagieren Sie mit der Seite und ändern Sie bei spät gemeldeten Metriken ihre Sichtbarkeit. Erwarten Sie nicht sämtliche Werte unmittelbar nach dem Laden. Ein Besuch ohne passende Interaktionen kann keinen INP-Wert haben; fehlende Werte dürfen nicht als null gespeichert werden.
Ersetzen Sie für echte Nutzermessungen die Konsolenausgabe durch eine bewusst entworfene Telemetrie. Definieren Sie Stichproben, gegebenenfalls Einwilligung, Datenminimierung und Deduplizierung. Bewahren Sie Metrik-ID und Namen auf und behandeln Sie Aktualisierungen entsprechend der Bibliotheksversion. LCP und INP sind Zeitwerte, CLS ist einheitenlos. Vermischen Sie keine Einheiten und zählen Sie mehrere Aktualisierungen nicht als mehrere Besuche.
Routenwechsel verlangen zusätzliche Sorgfalt. Das Messverhalten bei Soft-Navigationen hängt von Browser und Bibliothek ab. Unterstellen Sie nicht, dass eine clientseitige URL-Änderung sämtliche Standardmetriken zurücksetzt. Ordnen Sie einen späten Messwert auch nicht einfach der gerade sichtbaren URL zu. Dokumentieren Sie die Navigationssemantik der tatsächlich ausgelieferten Version.
Veröffentlichen Sie eine Änderung mit klarer Abnahmeprüfung
Wählen Sie den Engpass, nehmen Sie die kleinste passende Änderung vor und wiederholen Sie denselben Ablauf unter vergleichbaren Bedingungen. Bei Bildern prüfen Sie Anfragezeitpunkt, Bildkandidat und LCP. Bei Client-Grenzen prüfen Sie Bundle-Inhalt, Reaktionszeit und Funktion. Bei Layoutänderungen untersuchen Sie das Laden und spätere Inhaltsaktualisierungen.
Interpretieren Sie Messwerte mit dem Core-Web-Vitals-Prüfer und beobachten Sie anschließend die betroffenen Produktionsrouten und Gerätegruppen. Halten Sie die Leitfäden zur Plattformoptimierung bei der Release-Checkliste bereit. Der nächste sinnvolle Schritt ist eine dokumentierte Verbesserung mit klarer Ursache und anschließender Regressionsprüfung der übrigen Nutzung.