Eine vollständige Anleitung zur inkrementellen statischen Regenerierung (ISR) mit Next.js

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Incremental Static Regeneration (ISR) ist eine neue Weiterentwicklung des Jamstack, mit der Sie statische Inhalte sofort aktualisieren können, ohne dass Ihre Website vollständig neu erstellt werden muss. Der hybride Ansatz von Next.js ermöglicht es Ihnen, ISR für E-Commerce, Marketingseiten, Blogposts, werbefinanzierte Medien und mehr zu verwenden.

Vor einem Jahr hat Next.js 9.3 die Unterstützung für Static Site Generation (SSG) veröffentlicht und ist damit das erste Hybrid-Framework. Zu diesem Zeitpunkt war ich seit einigen Jahren ein zufriedener Next.js-Benutzer, aber diese Version machte Next.js zu meiner neuen Standardlösung. Nachdem ich intensiv mit Next.js gearbeitet hatte, kam ich zu Vercel, um Unternehmen wie Tripadvisor und Washington Post bei der Einführung und Skalierung von Next.js zu unterstützen.

In diesem Artikel möchte ich eine neue Evolution des Jamstacks untersuchen: Incremental Static Regeneration (ISR) . Nachfolgend finden Sie einen Leitfaden zu ISR – einschließlich Anwendungsfällen, Demos und Kompromissen.

Das Problem mit der Static-Site-Generierung

Die Idee hinter dem Jamstack ist ansprechend: vorgerenderte statische Seiten, die auf ein CDN gepusht werden können und in Sekundenschnelle global verfügbar sind. Statische Inhalte sind schnell, ausfallsicher und werden sofort von Crawlern indiziert. Aber es gibt einige Probleme.

Wenn Sie die Jamstack-Architektur übernommen haben, während Sie eine umfangreiche statische Website erstellt haben, müssen Sie möglicherweise stundenlang warten, bis Ihre Website erstellt wurde. Wenn Sie die Anzahl der Seiten verdoppeln, verdoppelt sich auch die Bauzeit. Betrachten wir Target.com. Ist es möglich, bei jeder Bereitstellung Millionen von Produkten statisch zu generieren?

Zeitdiagramm erstellen
Das Problem bei der Generierung statischer Websites: Da die Erstellungszeiten linear mit der Anzahl der Seiten skalieren, müssen Sie möglicherweise stundenlang auf die Erstellung Ihrer Website warten. (Große Vorschau)

Selbst wenn jede Seite statisch in unrealistischen 1 ms generiert wurde, würde es immer noch Stunden dauern, die gesamte Website neu aufzubauen . Für große Webanwendungen ist die Wahl einer vollständigen Generierung statischer Sites ein Fehlstart. Große Teams benötigen eine flexiblere, personalisierte Hybridlösung.

Content-Management-Systeme (CMS)

Für viele Teams ist der Inhalt ihrer Website vom Code entkoppelt. Die Verwendung eines Headless CMS ermöglicht es Content-Redakteuren, Änderungen zu veröffentlichen, ohne einen Entwickler einzubeziehen. Bei herkömmlichen statischen Websites kann dieser Vorgang jedoch langsam sein.

Stellen Sie sich einen E-Commerce-Shop mit 100.000 Produkten vor. Produktpreise ändern sich häufig. Wenn ein Content-Redakteur im Rahmen einer Werbeaktion den Preis für Kopfhörer von 100 $ auf 75 $ ändert, verwendet sein CMS einen Webhook, um die gesamte Website neu aufzubauen. Es ist nicht möglich, stundenlang auf den neuen Preis zu warten.

Lange Builds mit unnötiger Berechnung können auch zusätzliche Kosten verursachen. Idealerweise ist Ihre Anwendung intelligent genug, um zu verstehen, welche Produkte geändert wurden, und diese Seiten inkrementell zu aktualisieren, ohne dass eine vollständige Neuerstellung erforderlich ist .

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Inkrementelle statische Regeneration (ISR)

Mit Next.js können Sie statische Seiten erstellen oder aktualisieren, nachdem Sie Ihre Website erstellt haben. Incremental Static Regeneration (ISR) ermöglicht es Entwicklern und Content-Editoren, die statische Generierung auf Seitenbasis zu verwenden, ohne die gesamte Website neu erstellen zu müssen . Mit ISR können Sie die Vorteile der Statik beibehalten und gleichzeitig auf Millionen von Seiten skalieren.

Statische Seiten können zur Laufzeit (on-demand) anstatt zur Build-Zeit mit ISR generiert werden. Mithilfe von Analysen, A/B-Tests oder anderen Metriken sind Sie mit der Flexibilität ausgestattet, Ihre eigenen Kompromisse bei den Build-Zeiten einzugehen.

Betrachten Sie den E-Commerce-Shop von früher mit 100.000 Produkten. Bei realistischen 50 ms zum statischen Generieren jeder Produktseite würde dies ohne ISR fast 2 Stunden dauern . Bei ISR ​​haben wir die Wahl zwischen:

  • Schnellere Builds
    Generieren Sie die beliebtesten 1.000 Produkte zur Bauzeit. Anfragen an andere Produkte sind ein Cache-Mißerfolg und generieren statisch On-Demand: 1-Minute-Builds.
  • Höhere Cache-Trefferrate
    Generieren Sie 10.000 Produkte zur Build-Zeit, um sicherzustellen, dass mehr Produkte vor einer Benutzeranfrage zwischengespeichert werden: 8-Minuten-Builds.
Eine Abbildung zeigt Jamstack auf der linken Seite und Incremental Static Regenertion auf der rechten Seite
Der Vorteil von ISR: Sie können flexibel wählen, welche Seiten beim Build oder On-Demand generiert werden. Wählen Sie aus (A) schnelleren Builds oder (B) mehr Cache. (Große Vorschau)

Lassen Sie uns ein Beispiel für ISR für eine E-Commerce-Produktseite durchgehen.

Einstieg

Abrufen von Daten

Wenn Sie Next.js noch nie verwendet haben, empfehle ich Ihnen, Erste Schritte mit Next.js zu lesen, um die Grundlagen zu verstehen. ISR verwendet dieselbe Next.js-API, um statische Seiten zu generieren: getStaticProps . Durch Angabe von revalidate: 60 teilen wir Next.js mit, ISR für diese Seite zu verwenden.

Ein Diagramm des Anforderungsablaufs für die inkrementelle statische Regenerierung
Ein Diagramm des Anforderungsablaufs für die inkrementelle statische Regenerierung. (Große Vorschau)
  1. Next.js kann eine Revalidierungszeit pro Seite definieren. Stellen wir es auf 60 Sekunden ein.
  2. Die erste Anfrage an die Produktseite zeigt die zwischengespeicherte Seite mit dem ursprünglichen Preis.
  3. Die Daten zum Produkt werden im CMS aktualisiert.
  4. Alle Anfragen an die Seite nach der ersten Anfrage und vor 60 Sekunden werden zwischengespeichert und sofort ausgeführt.
  5. Nach dem 60-Sekunden-Fenster zeigt die nächste Anfrage immer noch die zwischengespeicherte (veraltete) Seite. Next.js löst im Hintergrund eine Neugenerierung der Seite aus.
  6. Sobald die Seite erfolgreich generiert wurde, macht Next.js den Cache ungültig und zeigt die aktualisierte Produktseite an. Wenn die Regenerierung im Hintergrund fehlschlägt, bleibt die alte Seite unverändert.
 // pages/products/[id].js export async function getStaticProps({ params }) { return { props: { product: await getProductFromDatabase(params.id) }, revalidate: 60 } }

Pfade generieren

Next.js definiert, welche Produkte zur Erstellungszeit und welche nach Bedarf generiert werden sollen. Lassen Sie uns nur die 1.000 beliebtesten Produkte zur Erstellungszeit generieren, indem getStaticPaths eine Liste der 1.000 wichtigsten Produkt-IDs bereitstellen.

Wir müssen konfigurieren, wie Next.js „zurückfällt“, wenn eines der anderen Produkte nach dem ersten Build angefordert wird. Es stehen zwei Optionen zur Auswahl: blocking und true .

  • fallback: blocking (bevorzugt)
    Wenn eine Anfrage an eine Seite gestellt wird, die noch nicht generiert wurde, rendert Next.js die Seite bei der ersten Anfrage auf dem Server. Zukünftige Anfragen werden die statische Datei aus dem Cache bereitstellen.
  • fallback: true
    Wenn eine Anfrage an eine Seite gestellt wird, die noch nicht generiert wurde, stellt Next.js bei der ersten Anfrage sofort eine statische Seite mit einem Ladezustand bereit. Wenn die Daten vollständig geladen sind, wird die Seite mit den neuen Daten erneut gerendert und zwischengespeichert. Zukünftige Anfragen werden die statische Datei aus dem Cache bereitstellen.
 // pages/products/[id].js export async function getStaticPaths() { const products = await getTop1000Products() const paths = products.map((product) => ({ params: { id: product.id } })) return { paths, fallback: 'blocking' } }

Kompromisse

Next.js konzentriert sich in erster Linie auf den Endbenutzer. Die „beste Lösung“ ist relativ und variiert je nach Branche, Zielgruppe und Art der Anwendung. Indem es Entwicklern ermöglicht, zwischen Lösungen zu wechseln, ohne die Grenzen des Frameworks zu verlassen, können Sie mit Next.js das richtige Tool für das Projekt auswählen.

Serverseitiges Rendern

ISR ist nicht immer die richtige Lösung. Beispielsweise kann der Facebook-Newsfeed keine veralteten Inhalte anzeigen. In diesem Fall möchten Sie SSR und möglicherweise Ihre eigenen cache-control Header mit Ersatzschlüsseln verwenden, um Inhalte ungültig zu machen. Da Next.js ein hybrides Framework ist, können Sie diesen Kompromiss selbst eingehen und innerhalb des Frameworks bleiben.

 // You can cache SSR pages at the edge using Next.js // inside both getServerSideProps and API Routes res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate');

SSR und Edge-Caching ähneln ISR (insbesondere bei Verwendung von stale-while-revalidate Caching-Headern), wobei der Hauptunterschied in der ersten Anforderung besteht. Mit ISR kann die erste Anfrage statisch garantiert werden, wenn sie vorgerendert wird. Selbst wenn Ihre Datenbank ausfällt oder ein Problem bei der Kommunikation mit einer API auftritt, sehen Ihre Benutzer immer noch die ordnungsgemäß bereitgestellte statische Seite. SSR ermöglicht es Ihnen jedoch, Ihre Seite basierend auf der eingehenden Anfrage anzupassen.

Hinweis : Die Verwendung von SSR ohne Caching kann zu schlechter Leistung führen. Jede Millisekunde zählt, wenn es darum geht, den Benutzer daran zu hindern, Ihre Website zu sehen, und dies kann dramatische Auswirkungen auf Ihre TTFB (Time to First Byte) haben.

Static-Site-Generierung

ISR ist für kleine Websites nicht immer sinnvoll. Wenn Ihr Revalidierungszeitraum länger ist als die Zeit, die für die Neuerstellung Ihrer gesamten Site benötigt wird, können Sie auch die herkömmliche Generierung statischer Sites verwenden.

Clientseitiges Rendern

Wenn Sie React ohne Next.js verwenden, verwenden Sie clientseitiges Rendering. Ihre Anwendung dient einem Ladezustand, gefolgt von der Anforderung von Daten innerhalb von JavaScript auf der Client-Seite (z. B. useEffect ). Während dies Ihre Optionen für das Hosting erhöht (da kein Server erforderlich ist), gibt es Kompromisse.

Das Fehlen von vorgerenderten Inhalten aus dem anfänglichen HTML führt zu einer langsameren und weniger dynamischen Suchmaschinenoptimierung (SEO). Es ist auch nicht möglich, CSR mit deaktiviertem JavaScript zu verwenden.

ISR-Fallback-Optionen

Wenn Ihre Daten schnell abgerufen werden können, sollten Sie fallback: blocking verwenden. Dann brauchen Sie den Ladezustand nicht zu berücksichtigen und Ihre Seite zeigt immer das gleiche Ergebnis (unabhängig davon, ob sie zwischengespeichert ist oder nicht). Wenn Ihr Datenabruf langsam ist, können Sie mit fallback: true dem Benutzer sofort einen Ladestatus anzeigen.

ISR: Nicht nur Caching!

Während ich ISR im Zusammenhang mit einem Cache erklärt habe, ist es so konzipiert, dass Ihre generierten Seiten zwischen Bereitstellungen bestehen bleiben . Dies bedeutet, dass Sie sofort ein Rollback durchführen können und Ihre zuvor generierten Seiten nicht verlieren.

Jede Bereitstellung kann durch eine ID verschlüsselt werden, die Next.js verwendet, um statisch generierte Seiten beizubehalten. Wenn Sie ein Rollback durchführen, können Sie den Schlüssel so aktualisieren, dass er auf die vorherige Bereitstellung verweist, was atomare Bereitstellungen ermöglicht. Das bedeutet, dass Sie Ihre vorherigen unveränderlichen Bereitstellungen aufrufen können und sie wie beabsichtigt funktionieren.

  • Hier ist ein Beispiel für das Zurücksetzen von Code mit ISR:
  • Sie drücken Code und erhalten eine Bereitstellungs-ID 123.
  • Ihre Seite enthält einen Tippfehler „Smshng Magazine“.
  • Sie aktualisieren die Seite im CMS. Keine erneute Bereitstellung erforderlich.
  • Sobald auf Ihrer Seite „Smashing Magazine“ angezeigt wird, wird sie dauerhaft gespeichert.
  • Sie pushen einen schlechten Code und stellen ID 345 bereit.
  • Sie führen ein Rollback auf Bereitstellungs-ID 123 durch.
  • Sie sehen immer noch „Smashing Magazine“.

Zurücksetzungen und dauerhafte statische Seiten liegen außerhalb des Bereichs von Next.js und hängen von Ihrem Hosting-Provider ab. Beachten Sie, dass sich ISR vom Server-Rendering mit Cache-Control Headern unterscheidet, da Caches ablaufen. Sie werden nicht über Regionen hinweg geteilt und werden beim Zurücksetzen gelöscht.

Beispiele für inkrementelle statische Regenerierung

Die inkrementelle statische Regeneration eignet sich gut für E-Commerce, Marketingseiten, Blogbeiträge, werbefinanzierte Medien und mehr.

  • E-Commerce-Demo
    Next.js Commerce ist ein All-in-One-Starterkit für leistungsstarke E-Commerce-Websites.
  • GitHub Reactions-Demo
    Reagieren Sie auf das ursprüngliche GitHub-Problem und beobachten Sie, wie ISR die statisch generierte Zielseite aktualisiert.
  • Statische Tweets-Demo
    Dieses Projekt wird in 30 Sekunden bereitgestellt, kann aber mit ISR statisch 500 Millionen Tweets bei Bedarf generieren.

Lernen Sie noch heute Next.js kennen

Entwickler und große Teams entscheiden sich für Next.js wegen seines hybriden Ansatzes und der Fähigkeit, Seiten bei Bedarf inkrementell zu generieren. Mit ISR erhalten Sie die Vorteile der Statik mit der Flexibilität des Server-Renderings. ISR funktioniert out of the box mit next start .

Next.js wurde für eine schrittweise Einführung entwickelt. Mit Next.js können Sie Ihren bestehenden Code weiterverwenden und so viel (oder so wenig) React hinzufügen, wie Sie benötigen. Indem Sie klein anfangen und schrittweise weitere Seiten hinzufügen, können Sie verhindern, dass die Arbeit der Funktionen entgleist, indem Sie ein vollständiges Neuschreiben vermeiden. Erfahren Sie mehr über Next.js – und allen viel Spaß beim Programmieren!

Weiterführende Lektüre

  • Erste Schritte mit Next.js
  • Vergleich von Styling-Methoden in Next.js
  • So erstellen Sie einen GraphQL-Server mit Next.js-API-Routen