Leistung mit Partial Prerendering in Next.js freischalten
Takashi Yamamoto
Infrastructure Engineer · Leapcell

Verbesserung der Webperformance mit Partial Prerendering in Next.js
In der sich schnell entwickelnden Landschaft der Webentwicklung sind Benutzererfahrung und Leistung von größter Bedeutung. Wir streben ständig danach, blitzschnelle, hochinteraktive Anwendungen zu liefern und gleichzeitig eine hervorragende Suchmaschinenoptimierung (SEO) zu gewährleisten. Das Erreichen dieser Balance, insbesondere bei dynamischen Inhalten, war historisch gesehen eine große Herausforderung. Traditionelle Ansätze zwangen Entwickler oft zu einer Wahl zwischen den SEO-Vorteilen des serverseitigen Renderings (SSR) oder der dynamischen Interaktivität des clientseitigen Renderings (CSR). Hier erweist sich Partial Prerendering (PPR) als bahnbrechend im Next.js-Framework und bietet eine ausgeklügelte Lösung, die diese Lücke schließt und eine neue Ära der Webperformance und Entwicklereffizienz verspricht.
Die Kernkonzepte verstehen
Bevor wir uns mit den praktischen Aspekten von PPR befassen, ist es entscheidend, einige grundlegende Konzepte zu verstehen, die seine Funktionsweise und Vorteile untermauern:
- Serverseitiges Rendering (SSR): Eine Rendering-Strategie, bei der der Server bei jeder Anfrage das vollständige HTML für eine Seite generiert. Dies bietet sofortige Inhalte, gute SEO und Zugänglichkeit, kann aber bei hochdynamischen Seiten aufgrund wiederholter serverseitiger Berechnungen langsam sein.
- Clientseitiges Rendering (CSR): Der Browser empfängt eine minimale HTML-Hülle, und JavaScript ruft dann Daten ab und rendert den Inhalt direkt im Client. Dies bietet große Interaktivität, kann jedoch zu langsameren anfänglichen Ladezeiten (leerer Bildschirm) und schlechterer SEO führen, wenn Crawler Schwierigkeiten haben, JavaScript auszuführen.
- Generierung statischer Websites (SSG): Seiten werden zur Build-Zeit in statische HTML-Dateien vorgerendert. Dies bietet extreme Geschwindigkeit und Skalierbarkeit, ist jedoch nur für Inhalte geeignet, die sich nicht häufig ändern.
- React Server Components (RSC): Ein neues Paradigma, das von React eingeführt wurde und es Entwicklern ermöglicht, Komponenten auf dem Server zu rendern und sie an den Client zu streamen. Dies ermöglicht eine feinere Kontrolle darüber, was wo gerendert wird, verbessert die Leistung und reduziert die Bundle-Größen auf der Client-Seite.
Partial Prerendering (PPR) kombiniert die besten Aspekte dieser Strategien. Im Wesentlichen ist PPR eine Optimierung, die auf React Server Components und der Rendering-Engine von Next.js aufbaut. Es ermöglicht, dass bestimmte Teile einer Seite zur Build-Zeit (oder bei der ersten Anfrage und zwischengespeichert) statisch vorgerendert werden, während andere, dynamischere Teile bei Bedarf vom Server gestreamt werden. Das bedeutet, dass Benutzer fast sofort eine schnelle, vollständig aussehende Seite erhalten, wobei dynamische Elemente die Erfahrung schrittweise verbessern.
Wie Partial Prerendering funktioniert und seine praktische Anwendung
Die Eleganz von PPR liegt in seinen "Fallbacks". Wenn Sie einen dynamischen Teil Ihrer Seite definieren, können Sie einen "Fallback"-Ladezustand bereitstellen. Next.js liefert fast sofort den vorgerenderten statischen Inhalt und zeigt den Fallback für die dynamischen Abschnitte an. Sobald die dynamischen Daten vom Server verfügbar sind (über React Server Components), werden diese Abschnitte hydriert und zeigen die frischen Inhalte an.
Lassen Sie uns ein gängiges Szenario veranschaulichen: eine E-Commerce-Produktseite.
Stellen Sie sich eine Produktseite mit Folgendem vor:
- Statische Elemente: Produktbild, Titel, Beschreibung, Preis (diese ändern sich pro Anfrage oft nicht).
- Dynamische Elemente: Echtzeit-Lagerbestand, personalisierte Empfehlungen, Benutzerbewertungen (diese ändern sich häufig).
Ohne PPR würden Sie normalerweise wählen zwischen:
- SSR: Jede Anfrage baut die gesamte Seite neu auf, einschließlich statischer Teile, was die anfängliche Darstellung verlangsamen kann.
- SSG + CSR für dynamische Teile: Sie würden die statischen Teile generieren, aber dann würde eine Leerfläche erscheinen, wo dynamische Inhalte sein sollten, die erst gefüllt wird, nachdem clientseitige JS sie abruft und rendert.
Mit PPR können Sie das Beste aus beiden Welten erreichen. Hier ist ein vereinfachtes Codebeispiel, das das Konzept demonstriert:
Angenommen, Sie haben eine ProductPage
-Komponente:
// app/product/[slug]/page.js import { Suspense } from 'react'; import ProductDetails from '@/components/ProductDetails'; import RecommendedProducts from '@/components/RecommendedProducts'; import UserReviews from '@/components/UserReviews'; import ProductSkeleton from '@/components/ProductSkeleton'; // Ein Lade-Skelett für dynamische Inhalte export default function ProductPage({ params }) { const { slug } = params; return ( <div className="container mx-auto p-4"> <ProductDetails slug={slug} /> {/* Dies könnte eine Server-Komponente sein, die statische Produktdaten abruft */} <h2 className="text-2xl font-bold mt-8 mb-4">Das könnte Ihnen auch gefallen</h2> <Suspense fallback={<ProductSkeleton count={3} />}> <RecommendedProducts slug={slug} /> {/* Dynamische Server-Komponente mit Fallback */} </Suspense> <h2 className="text-2xl font-bold mt-8 mb-4">Kundenrezensionen</h2> <Suspense fallback={<p>Rezensionen werden geladen...</p>}> <UserReviews slug={slug} /> {/* Dynamische Server-Komponente mit Fallback */} </Suspense> </div> ); } // components/ProductDetails.js (Server-Komponente) async function ProductDetails({ slug }) { // Statische Produktdaten aus einer Datenbank oder API abrufen const product = await fetch(`https://api.example.com/products/${slug}`).then(res => res.json()); return ( <div> <img src={product.imageUrl} alt={product.name} className="w-full h-64 object-cover" /> <h1 className="text-3xl font-bold mt-4">{product.name}</h1> <p className="text-xl text-gray-700">${product.price.toFixed(2)}</p> <p className="mt-2">{product.description}</p> </div> ); } // components/RecommendedProducts.js (Server-Komponente - dynamisch) async function RecommendedProducts({ slug }) { // Simuliere einen langsamen API-Aufruf für dynamische Empfehlungen await new Promise(resolve => setTimeout(resolve, 1500)); const recommendations = await fetch(`https://api.example.com/recommendations?product=${slug}`).then(res => res.json()); return ( <div className="grid grid-cols-3 gap-4"> {recommendations.map(reco => ( <div key={reco.id} className="border p-2"> <p>{reco.name}</p> <p>${reco.price.toFixed(2)}</p> </div> ))} </div> ); } // components/UserReviews.js (Server-Komponente - dynamisch) async function UserReviews({ slug }) { // Simuliere einen weiteren langsamen API-Aufruf für Benutzerbewertungen await new Promise(resolve => setTimeout(resolve, 2000)); const reviews = await fetch(`https://api.example.com/reviews?product=${slug}`).then(res => res.json()); return ( <div className="mt-4"> {reviews.length === 0 ? <p>Noch keine Bewertungen.</p> : ( reviews.map(review => ( <div key={review.id} className="border-b py-2"> <p className="font-bold">{review.user}</p> <p>{review.comment}</p> </div> )) )} </div> ); }
In diesem Beispiel:
ProductDetails
ist eine Server-Komponente, die die Kernproduktdaten abruft. Aufgrund von PPR kann dieser Teil der Seite serverseitig gerendert und sofort an den Client gestreamt werden. Wenn die Daten stabil sind, kann Next.js sogar das vollständige HTML für diesen Abschnitt cachen.RecommendedProducts
undUserReviews
sind ebenfalls Server-Komponenten, aber sie sind inSuspense
-Grenzen verpackt. Dies teilt Next.js mit, dass das Laden dieser Komponenten länger dauern kann.- Wenn ein Benutzer diese Seite anfordert, rendert Next.js schnell
ProductDetails
(möglicherweise aus dem Cache) und diefallback
-UI fürRecommendedProducts
undUserReviews
. - Im Hintergrund ruft der Server weiterhin die Daten für
RecommendedProducts
undUserReviews
ab. Sobald sie fertig sind, werden diese Komponenten auf dem Server gerendert und als HTML an den Client gestreamt, wobei ihre jeweiligen Fallbacks nahtlos ersetzt werden.
Vorteile von Partial Prerendering
Die Vorteile der Einführung von PPR sind umfangreich:
- Sofortige initiale Ladezeit: Benutzer sehen viel schneller bedeutungsvolle Inhalte, da die statische Hülle und nicht-dynamische Teile fast sofort geliefert werden. Dies verbessert die wahrgenommene Leistung erheblich.
- Überlegene Benutzererfahrung: Dynamische Inhalte werden progressiv geladen, ohne die anfängliche Darstellung zu blockieren, was ein flüssigeres und reaktionsschnelleres Gefühl bietet, ähnlich wie bei CSR, aber mit der anfänglichen Geschwindigkeit von SSG.
- Verbesserte SEO: Suchmaschinen-Crawler erhalten eine vollständig ausgebildete HTML-Seite, einschließlich des vorgerenderten statischen Inhalts, was eine hervorragende Indizierbarkeit und Auffindbarkeit gewährleistet, im Gegensatz zu reinem CSR.
- Reduzierte Serverlast für statische Teile: Bei beliebten Seiten kann die statische Hülle und stabile Teile effizient gecacht werden, wodurch die Rechenlast auf dem Server für nachfolgende Anfragen reduziert wird.
- Optimierte Bundle-Größe: Durch das Rendern von mehr Komponenten auf dem Server muss weniger JavaScript an den Client gesendet werden, was zu kleineren Bundle-Größen und schnellerer Skriptausführung führt.
- Vereinfachte Datenabfrage: Die Integration mit Server-Komponenten ermöglicht direkte Datenbankabfragen oder sichere API-Aufrufe auf dem Server und vereinfacht die Datenabfrage-Logik, ohne sensible Schlüssel an den Client preiszugeben.
- Flexibilität zwischen statisch und dynamisch: PPR ermöglicht es Entwicklern, präzise zu steuern, welche Teile einer Seite statisch und welche dynamisch sind, und bietet beispiellose Flexibilität bei der Balance von Leistung und Aktualität.
Fazit
Partial Prerendering in Next.js, unterstützt durch React Server Components und Suspense
, stellt einen monumentalen Sprung nach vorne bei der Bewältigung der Komplexität moderner Webanwendungsentwicklung dar. Es kombiniert elegant die Geschwindigkeit statischer Websites, die SEO-Vorteile des Server-Renderings und die dynamische Interaktivität clientseitiger Erlebnisse. Durch die intelligente Orchestrierung, welche Inhalte wann geliefert werden, ermöglicht PPR Entwicklern den Aufbau von performanten, benutzerzentrierten und SEO-freundlichen Anwendungen, die wirklich ein außergewöhnliches Web-Erlebnis bieten. Es ist ein leistungsfähiges Paradigma, das die Kern-Web-Vitals erheblich verbessert und einen neuen Standard für die effiziente Inhaltsbereitstellung im Web setzt.