Next.js Incremental Static Regeneration vs SSR – eine tiefgehende Analyse von Leistung und Kosten

Wir vergleichen ISR und SSR in Next.js hinsichtlich Renderzeit, Ressourcenkosten und praktischen Migrationshinweisen.

Next.js Incremental Static Regeneration vs SSR – dogłębna analiza wydajności i kosztów

Next.js ist de‑facto zum Standard für den Bau moderner React‑Anwendungen geworden, und die beiden wichtigsten Render‑Modi – Incremental Static Regeneration (ISR) und Server‑Side Rendering (SSR) – werfen häufig Fragen bei der Architekturwahl auf. In diesem Artikel werfen wir einen Blick auf ihre internen Mechanismen, messen die reale Renderzeit, schätzen die Ressourcenkosten und geben Hinweise, wann welches Verfahren sinnvoll ist.

Wie funktioniert Incremental Static Regeneration?

ISR kombiniert die Vorteile der statischen Generierung (SSG) mit der Möglichkeit, Inhalte nach dem Deployment zu aktualisieren. Beim ersten Request erzeugt Next.js HTML und speichert es im Cache (Edge oder CDN). Bei nachfolgenden Requests liefert der Server die bereits gecachte Datei aus, und im Hintergrund, wenn das in getStaticProps definierte revalidate abgelaufen ist, wird ein neuer Build gestartet.

export async function getStaticProps() {
  const data = await fetchAPI();
  return {
    props: { data },
    revalidate: 60 // alle 60 s aktualisieren
  };
}

Der Mechanismus beruht auf der Funktion unstable_revalidate (seit Next.js 13) oder einer internen Lambda/Edge‑Aufrufwarteschlange. Dadurch muss kein permanenter Server im „Ready‑State“ laufen – nur eine kurze Funktion, die eine neue Version der Seite erzeugt.

Server‑Side Rendering – Klassiker mit modernem Cache

SSR rendert die Seite bei jedem Request, indem getServerSideProps aufgerufen wird. Das Ergebnis wird direkt an den Browser gesendet, und React „hydratisiert“ anschließend die interaktive UI. In der Praxis erfordert SSR einen ständig laufenden Node‑Prozess, was zu höherem Speicher‑ und CPU‑Verbrauch führt.

export async function getServerSideProps(context) {
  const data = await fetchAPI(context.params.id);
  return { props: { data } };
}

Die Performance von SSR lässt sich durch eine Cache‑Schicht (z. B. stale‑while‑revalidate in Vercel Edge) oder durch Memoisierung von Abfragen verbessern, aber jeder Request muss dennoch im Node‑Prozess verarbeitet werden.

Vergleich von ISR und SSR in Next.js – Renderzeiten und Kosten

  • Cold‑Start ISR: Der erste Request nach dem Deploy erzeugt HTML – Kosten ähnlich wie bei SSR, aber einmalig.
  • Warm ISR: Folgende Requests liefern die statische Datei vom CDN – Latenz 20‑40 ms bei globaler Verteilung.
  • SSR: Jeder Request erfordert einen vollen Node‑Durchlauf – typischerweise 120‑250 ms je nach Komplexität der Abfragen.
  • Kosten: ISR zahlt nur für CDN‑Storage und sporadische Lambda‑Aufrufe; SSR zahlt für ständig laufende Instanzen (CPU, RAM) sowie für den Transfer.

In der Praxis werden die Unterschiede bei hohem RPS (Requests per Second) kritisch. Bei 10 000 RPS kann ISR den Traffic mit minimalen Kosten bedienen, während SSR horizontales Skalieren erfordert, was die Rechnung erhöht.

Wann ISR einsetzen und wann nicht?

  • ISR: Inhalte, die selten wechseln (z. B. Blog, Produktkatalog), SEO‑relevant, aber ein revalidate‑Intervall tolerieren.
  • SSR: Daten, die sofort aktualisiert werden müssen (z. B. Warenkorb, personalisierte Ansicht nach Login), dynamische UI, die von Session‑Daten abhängt.

Benötigt Ihre Anwendung eine Mischung – Sie können beide Ansätze im selben Projekt kombinieren, indem Sie getStaticProps für öffentliche Seiten und getServerSideProps für geschützte Bereiche definieren.

Fallstricke bei der Migration von SSR zu ISR

Der Umstieg ist nicht trivial. Die häufigsten Probleme sind:

  • Vergessene Abhängigkeiten von req/res im Code – ISR hat keinen Zugriff auf das Request‑Objekt.
  • Cache‑stale‑Data – nicht aktualisierte Daten nach einer DB‑Änderung, wenn revalidate zu lang ist.
  • Fehlende Unterstützung von Autorisierungs‑Headern im CDN, wodurch personalisierte Seiten nicht ausgeliefert werden können.

Die Lösung besteht darin, die Geschäftslogik in eine Service‑Schicht (z. B. Mikroservice) auszulagern und in den Komponenten nur reine Daten zu verwenden.

„Es geht nicht darum, welcher Ansatz schneller ist, sondern welcher besser zu den Anforderungen Ihres Produkts passt.“

Praktische Checkliste für die Migration SSR → ISR

  • Identifizieren Sie Seiten, die keine kontextbezogenen Daten (Session, Auth) benötigen.
  • Finden Sie Stellen, an denen req.headers verwendet wird – verlagern Sie diese in API‑Routes.
  • Setzen Sie ein sinnvolles revalidate‑Intervall basierend auf der Änderungsfrequenz Ihrer Daten.
  • Führen Sie Performance‑Tests (k6, Artillery) vor und nach der Migration durch.
  • Überwachen Sie Cache‑Misses in Vercel Analytics oder eigenem Prometheus.

Typische Fehler und architektonische Kompromisse

Viele Teams machen den Fehler „ISR‑by‑default“, was zu unbewusstem Ausliefern veralteter Daten führt. Die Lösung ist die Implementierung von Webhooks, die nach jeder Datenbank‑Änderung unstable_revalidate auslösen.

Ein weiterer Kompromiss ist die übermäßige Abhängigkeit vom CDN‑Cache bei dynamischen Komponenten. In solchen Fällen sollte ein Teil der UI auf Client‑Side Rendering (CSR) umgestellt werden, während das Grundgerüst statisch von ISR erzeugt bleibt.

Zusammenfassend sollte die Wahl zwischen Next.js Incremental Static Regeneration und SSR auf einer Analyse der Inhaltsänderungsfrequenz, SEO‑Anforderungen und erwarteter Last basieren. Mit einer bewussten Caching‑Strategie und geeigneter Code‑Segmentierung lassen sich erhebliche Kosteneinsparungen und eine verbesserte User‑Experience erzielen.

Wenn Sie Unterstützung bei der Optimierung Ihrer Next.js‑Architektur oder bei der Migration SSR → ISR benötigen, steht Ihnen unser Team von Coderia.it gerne zur Verfügung – kontaktieren Sie uns noch heute.

Loslegen

Ein Projekt im Kopf?

Beschreiben Sie es in wenigen Sätzen. Ich antworte innerhalb von 24 Stunden mit Angebot und Stack-Vorschlag.