Next.js 16 Cache Components: Leitfaden zur Migration

Next.js 16 Cache Components: Leitfaden zur Migration

Migrationsplan für use cache und cacheLife, Tag-Invalidierung sowie mehrere Next.js-Instanzen.

export const revalidate = 3600 legt in einer App-Router-Anwendung ein Revalidierungsintervall auf Segmentebene fest. Mit aktivierten Cache Components steht diese Segmentsteuerung nicht mehr zur Verfügung. Die Migration ist kein Austausch von Direktiven. Cache-Grenzen liegen danach näher an den Funktionen und Komponenten, die Daten laden. Eine mechanische Umstellung scheitert bei Zugriffen auf Cookies oder Header und erzeugt zu viele Cache-Einträge, wenn Sitzungswerte als Argumente einfließen.

Was ändert sich beim Next.js 16 Caching?

Cache Components machen Caching im App Router explizit. Dynamischer Code läuft bei der Anfrage, während use cache die Ergebnisse von Seiten, Komponenten oder Funktionen wiederverwendbar macht. Next.js kann diese Ergebnisse in die vorgerenderte HTML-Shell aufnehmen, sofern innerhalb der Cache-Grenze keine anfragebezogenen Daten gelesen werden.

Die Build-Konfiguration wird in next.config.ts aktiviert:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
}

export default nextConfig

Die vorgerenderte Shell kommt zuerst. Ein Suspense-Fallback reserviert darin den Platz für Daten, die erst bei der Anfrage vorliegen. Sobald der Server diese Daten aufgelöst hat, streamt React den fertigen Abschnitt in die bestehende Antwort. Vor der Umstellung erfasst ein Cache-Inventar deshalb jede bisherige Cache-Regel und jeden Zugriff auf anfragebezogene Daten.

Bestehende Cache-Konfiguration vor der Migration prüfen

Die Bestandsaufnahme umfasst page.tsx, layout.tsx, Route-Handler und Funktionen für den Datenzugriff. Folgende Fundstellen gehören in das Migrationsprotokoll:

  • Die Route-Segment-Einstellungen revalidate, dynamic und fetchCache
  • Funktionen mit unstable_cache und Aufrufe von fetch mit Cache-Optionen
  • Mutationen mit revalidateTag, updateTag oder revalidatePath
  • Zugriffe auf Cookies, Header, Suchparameter, Sitzungen und benutzerspezifische Datensätze

Für jeden Datensatz hält das Protokoll das zulässige Datenalter, den Aktualisierungsauslöser und die betroffenen Seiten fest. Das alte Segmentmodell entfällt. Mit aktivierten Cache Components steuern revalidate, dynamic und fetchCache das Rendering nicht mehr auf die bisherige Weise. Das Protokoll zeigt anschließend, welcher Inhalt in die statische Shell, in eine Cache-Grenze oder in den dynamischen Stream gehört.

Statische Shell, Cache-Grenze oder dynamischer Stream?

Zuordnung von Inhalten zu statischer Shell, Cache-Grenze und dynamischem Stream
Bereich Geeignete Inhalte Umsetzung
HTML-Shell Navigation, öffentliches Layout und vorab bekannte Inhalte Next.js rendert den Bereich vor und liefert ihn ohne Warten auf anfragebezogene Daten aus
Cache-Grenze Produktdaten, Kategorien oder Konfigurationen mit gemeinsamer Lebensdauer use cache, cacheLife und bei Bedarf cacheTag
Dynamischer Stream Sitzungen, Warenkörbe und Werte aus Cookies oder Headern Der Zugriff bleibt außerhalb des gemeinsamen Caches und liegt hinter einer Suspense-Grenze

Argumente und Werte aus dem umgebenden Gültigkeitsbereich fließen in den Schlüssel einer gecachten Funktion ein. Wenige festgelegte Werte, etwa die unterstützte Sprache oder Währung, begrenzen die Zahl der Varianten und lassen sich für viele Anfragen wiederverwenden. Sitzungs-IDs vervielfachen den Cache. Die Schulung Next.js App Router: Skalierbare Webarchitektur vertieft diese Trennung anhand von Server Components, Streaming und Tag-Invalidierung. Nach der Zuordnung erhält jede Cache-Grenze ein passendes cacheLife-Profil.

Von revalidate zu cacheLife migrieren

cacheLife steuert drei Zeitfenster. stale legt fest, wie lange der Client einen Wert verwenden darf, ohne den Server erneut auf aktuellere Daten zu prüfen. Nach revalidate darf der Server einen vorhandenen Wert ausliefern und im Hintergrund erneuern. expire setzt die maximale Lebensdauer. Ist sie überschritten, wartet die Anfrage auf ein neues Ergebnis.

Next.js stellt folgende Profile bereit:

  • default
  • seconds
  • minutes
  • hours
  • days
  • weeks
  • max

Abweichende Zeitfenster erhalten ein benanntes Profil in next.config.ts:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
  cacheLife: {
    catalog: {
      stale: 300,
      revalidate: 900,
      expire: 3600,
    },
  },
}

export default nextConfig

Vor der Umstellung gilt das Intervall für das gesamte Route-Segment:

export const revalidate = 3600

export default async function ProductPage({ params }) {
  const { slug } = await params
  const product = await getProduct(slug)
  return <Product product={product} />
}

Danach trägt die wiederverwendbare Komponente ihr Zeitprofil und ihre Tags selbst:

import { cacheLife, cacheTag } from 'next/cache'

async function ProductDetails({ slug }: { slug: string }) {
  'use cache'
  cacheLife('catalog')
  cacheTag('products', `product-${slug}`)

  const product = await getProduct(slug)
  return <Product product={product} />
}

export default async function ProductPage({ params }) {
  const { slug } = await params
  return <ProductDetails slug={slug} />
}

Der Tag products invalidiert den gesamten Produktbestand. product-${slug} begrenzt die Invalidierung auf ein Produkt. Das Zeitprofil steuert die normale Alterung, während eine Mutation zwischen sofortigem Verwerfen und Aktualisieren im Hintergrund unterscheiden muss.

updateTag vs. revalidateTag: Entscheidungsmatrix

Vergleich von updateTag, revalidateTag und revalidatePath
API Verhalten Einsatz
revalidateTag(tag, 'max') Next.js markiert den Eintrag als veraltet und aktualisiert ihn beim nächsten Zugriff im Hintergrund Veraltete Katalog- oder redaktionelle Daten dürfen während der Aktualisierung ausgeliefert werden
updateTag(tag) Next.js verwirft den Eintrag sofort, sodass der nächste Zugriff auf neue Daten wartet Eine Server Action braucht nach einer Mutation Read-after-write-Konsistenz
revalidatePath(path, type) Next.js invalidiert die Cache-Daten eines Pfads oder einer durch den Typ bestimmten Route-Hierarchie Ein konkreter Pfad muss unabhängig von gemeinsam verwendeten Daten-Tags neu gerendert werden

Die Form revalidateTag(tag) mit nur einem Argument ist veraltet. updateTag ist auf Server Actions beschränkt. In einer Server Action sorgt die Funktion dafür, dass ein nach der Mutation gelesener Datensatz nicht aus dem alten Cache-Eintrag stammt. Vor dieser Entscheidung werden Cookies, Header und Suchparameter aus gemeinsam verwendeten Cache-Grenzen herausgelöst.

Cookies, Header und Suchparameter behandeln

cookies(), headers() und aufgelöste searchParams werden außerhalb einer gemeinsam verwendeten use cache-Funktion gelesen. Ein begrenzter Wert wie eine unterstützte Währung kann anschließend als Argument in den Cache-Schlüssel einfließen. Authentifizierungs-Token, Sitzungsobjekte und persönliche Profile bleiben im dynamischen Abschnitt, weil ihre Aufnahme in gemeinsame Cache-Grenzen unnötig viele Schlüssel erzeugt und bei fehlerhafter Schlüsselbildung Daten offenlegen kann.

Die Zahl möglicher Argumentkombinationen bestimmt die Cache-Kardinalität. Freie Suchtexte, Zeitstempel oder Benutzer-IDs erzeugen fortlaufend neue Schlüssel und verdrängen häufig verwendete Einträge. Bei mehreren Next.js-Instanzen kommt zur Schlüsselgestaltung die Frage hinzu, wo Einträge und Invalidierungsdaten gespeichert werden.

Cache Components mit Docker und Kubernetes betreiben

Eine selbst gehostete Next.js-Anwendung teilt ihren Standard-Cache nicht automatisch zwischen getrennten Instanzen. Zwei Container können deshalb unterschiedliche Datenstände ausliefern, wenn eine Tag-Invalidierung nur den lokalen Cache eines Prozesses erreicht. Ein Neustart entfernt lokale Einträge.

Horizontal skalierte Deployments benötigen einen gemeinsamen Cache-Handler mit einem zentralen Backend, etwa Redis. Der Handler muss sowohl die Cache-Werte als auch die Metadaten für Tags und Invalidierungen instanzübergreifend verwalten. Bei Rolling Deployments laufen alte und neue Replikate zeitweise parallel. Tests verteilen dieselbe Anfragesequenz deshalb bewusst auf beide Versionen und protokollieren die angesprochene Instanz. Cache-Handler, Suspense und Multi-Instanz-Konsistenz behandelt das Next.js Deep Dive Training: Caching & Skalierung; Betriebsmodelle mit Kubernetes finden sich unter Cloud-Native-Training. Ein reproduzierbarer Testplan weist danach nach, ob Lebensdauer und Invalidierung über Instanzwechsel hinweg funktionieren.

Testplan für Datenfrische und Performance

  1. Ein Baseline-Lauf misst Time to First Byte, Origin-Anfragen und Fehlerraten vor der Umstellung
  2. Kontrollierte Datenänderungen prüfen die Antworten innerhalb von stale, nach revalidate und nach expire
  3. Eine Mutation mit updateTag muss beim nächsten Lesen neue Daten liefern, während revalidateTag(tag, 'max') beim nächsten Zugriff zunächst den veralteten Wert ausliefern darf
  4. Mehrere Replikate beantworten dieselbe Anfragesequenz, während das Testprotokoll Cache-Treffer, Datenversion und angesprochene Instanz erfasst

Das Monitoring erfasst die Messwerte getrennt:

  • Das Alter der ausgelieferten Daten
  • Die Zahl der Cache-Treffer und Cache-Fehler
  • Die Fehlerrate der Anwendung
  • Die Antwortzeit nach Instanz und Version
  • Die Last auf der Datenbank oder der angebundenen API

Für jeden Wert erhält der Produktions-Rollout eine Rückkehrschwelle. Überschreitet der Canary eine dieser Schwellen, greift der vorbereitete Rollback.

Rollback-Checkliste für den Produktions-Rollout

cacheComponents ist eine Build-Konfiguration. Ein vollständiger Laufzeit-Feature-Flag kann die Funktion deshalb nicht unabhängig vom erzeugten Artefakt umschalten. Ein Canary-Deployment mit getrennten Artefakten hält die alte und die neue Konfiguration parallel verfügbar.

  • Die Baseline für Datenalter, Latenz, Fehlerrate und Origin-Last ist gespeichert
  • Die Rückkehrschwellen für veraltete Daten, steigende Antwortzeiten und zusätzliche Backend-Last sind vorab definiert
  • Das vorherige Deployment-Artefakt und seine Next.js-Konfiguration bleiben abrufbar
  • Der Canary erhält schrittweise mehr Anfragen, während jede Replikat-Version separat ausgewertet wird
  • Container-Neustarts, Rolling Updates und Tag-Invalidierungen wurden über alle Replikate geprüft

Lege vor dem ersten Canary eine Tabelle an, die jede alte Cache-Einstellung ihrer neuen use cache-Grenze, ihrem cacheLife-Profil und ihrem Invalidierungsauslöser zuordnet. Fehlt für einen Eintrag die Lebensdauer oder der Auslöser, bleibt dieser Datenfluss zunächst im alten Deployment.