Das Route-Caching von Astro speichert die gerenderte Antwort einer On-Demand-Seite, sodass ein Cache-Treffer das Rendern überspringt. EmDash liefert Cache-Tags für die Inhalte, die eine Seite rendert, und invalidiert diese Tags, sobald sich der Inhalt ändert. Seiten können tagelang im Cache bleiben, während eine Veröffentlichung in der Regel innerhalb weniger Sekunden sichtbar wird.
Der Objekt-Cache speichert Abfrageergebnisse und rendert weiterhin jede Seite. Ist ein Cache-Provider konfiguriert, überspringen anonyme Renderings den Objekt-Cache und lesen aus der Datenbank, sodass ein Rendering, das eine invalidierte Seite neu befüllt, nicht aus einem älteren Snapshot stammt (siehe Was wird zwischengespeichert). Der Route-Cache bedient dann anonyme Besucher, und der Objekt-Cache beschleunigt hauptsächlich Renderings für angemeldete Redakteure.
Cache-Provider auswählen
Route-Caching benötigt einen Cache-Provider. Verwenden Sie den, der zu Ihrer Bereitstellung passt:
| Bereitstellung | Provider | Import aus |
|---|---|---|
| Node.js | memoryCache() | astro/config |
| Cloudflare | cacheCloudflare() | @astrojs/cloudflare/cache |
memoryCache() hält Einträge im Arbeitsspeicher des Serverprozesses. cacheCloudflare() ist ein CDN-Provider: Er speichert Antworten im Cloudflare Workers Cache, und ein Cache-Treffer führt den Worker nie aus. Auch die Netlify- und Vercel-Adapter von Astro liefern CDN-Provider mit; siehe Adapter-Cache-Provider. EmDash invalidiert über die providerunabhängige cache.invalidate()-API von Astro, sodass seine Tags mit jedem Provider funktionieren. Unterschiede zwischen Providern behandelt das Verhalten, das vom Provider abhängt. astro dev cached nie, testen Sie das Caching daher mit einem Produktions-Build.
Route-Caching konfigurieren
Registrieren Sie den Provider und legen Sie fest, welche Routen gecacht werden dürfen, für wie lange und unter welchen Tags. Dieses Beispiel verwendet den Cloudflare-Provider; unter Node verwenden Sie cache: { provider: memoryCache() } mit memoryCache aus astro/config:
import { defineConfig } from "astro/config";
import { cacheCloudflare } from "@astrojs/cloudflare/cache";
export default defineConfig({
// ...Ihr bestehendes output, Ihr Adapter und Ihre Integrationen
cache: {
provider: cacheCloudflare(),
},
routeRules: {
"/": { maxAge: 86_400, swr: 604_800, tags: ["posts", "pages", "all"] },
"/blog": { maxAge: 86_400, swr: 604_800, tags: ["posts", "all"] },
"/blog/[slug]": { maxAge: 86_400, swr: 604_800, tags: ["posts", "all"] },
"/sitemap.xml": { maxAge: 86_400, swr: 604_800, tags: ["posts", "pages", "all"] },
"/sitemap-[collection].xml": { maxAge: 86_400, swr: 604_800, tags: ["posts", "pages", "all"] },
},
});
maxAgegibt an, wie lange der Cache den Eintrag ausliefert, bevor die Route erneut gerendert wird. EmDash invalidiert veraltete Einträge bei der Veröffentlichung (siehe unten), doch eine Invalidierung kann fehlschlagen. Deshalb begrenztmaxAgeauch, wie lange eine Seite veraltet bleiben kann, zuzüglich einer veralteten Antwort, währendswrsie neu validiert. Prüfen Sie Unterschiede zwischen Providern, bevor Sie einen langen Wert wählen.- Mit
swrkann der Cache einen veralteten Eintrag weiter ausliefern, während er ihn im Hintergrund neu validiert, sodass Besucher nur selten auf ein Rendering warten müssen, sobald eine Seite im Cache liegt. tagsbenennen den Eintrag für die Invalidierung. Versehen Sie jede Route mit den Collections, die sie rendert, und verwenden Sie dabei die Collection-Namen: Die integrierte Invalidierung von EmDash arbeitet mit Collection-Namen, daher werden passende Tags automatisch invalidiert. Ein breiter zusätzlicher Tag auf jeder gecachten Route (hierall, das kein Collection-Name ist und daher von EmDash nie von selbst invalidiert wird) dient als Notschalter: Wird er invalidiert, zum Beispiel mitcontext.cache.invalidate({ tags: ["all"] })in einem von Ihnen selbst abgesicherten Endpunkt, wird alles auf einmal geleert.
Die Query-Helper liefern außerdem einen cacheHint, den Sie innerhalb der Seite an Astro.cache.set() übergeben können. Seine Tags benennen den genauen Eintrag (getEmDashEntry), die Collection (getEmDashCollection) oder die Chrome-Ressource (getMenuWithCacheHint, getSiteSettingsWithCacheHint, getTaxonomyTermsWithCacheHint, getWidgetAreaWithCacheHint). Das sind dieselben Tags, die EmDash bei Schreibvorgängen invalidiert. Eine Seite, die ihre Hints übergibt, wird daher invalidiert, wenn ein Eintrag oder eine Chrome-Ressource geschrieben wird, die sie rendert, auch solche, die ihre Route-Regel nicht nennt:
---
import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
if (!slug) return Astro.rewrite("/404");
const { entry, cacheHint } = await getEmDashEntry("posts", slug);
if (Astro.cache?.enabled) Astro.cache.set(cacheHint);
---
Astro.cache.set() wird mit der Route-Regel zusammengeführt, und Tags sammeln sich über mehrere Aufrufe hinweg an. Die Cache-Hints enthalten Tags, aber kein maxAge, daher bestimmt die Route-Regel, wie lange eine Seite gecacht wird.
Geben Sie jeder öffentlichen Route eine explizite Regel. Regeln treffen auf den Anfragepfad zu, listen Sie Ihre öffentlichen Routen daher einzeln auf: Ein Rest-Parameter an der Site-Wurzel, etwa /[...slug], trifft auch auf die Admin- und API-Routen unter /_emdash/ zu.
Invalidierung bei der Veröffentlichung ist integriert
Die Content-API-Routen von EmDash invalidieren den Route-Cache, sobald sich Live-Inhalte ändern: Das Veröffentlichen, Zurückziehen, Löschen oder Wiederherstellen eines Eintrags aus dem Papierkorb sowie das Speichern von Änderungen, die den Live-Eintrag erreichen, invalidieren die Tags [collection, id]. Das Erstellen oder Duplizieren eines Eintrags invalidiert nichts, da der neue Eintrag ein Entwurf ist. Jede Route-Regel, die mit dem Collection-Namen getaggt ist (wie oben), wird daher in der Regel innerhalb weniger Sekunden nach einer Veröffentlichung aktualisiert, selbst bei langem maxAge.
Auch das Site-Chrome ist abgedeckt: Das Speichern der Site-Einstellungen invalidiert emdash:settings, Menübearbeitungen invalidieren emdash:menu:{name}, und Schreibvorgänge bei Taxonomien und Widget-Bereichen invalidieren die zugehörigen Tags emdash:taxonomy:{name} bzw. emdash:widget-area:{name}. Seiten übernehmen diese Tags automatisch, wenn sie den cacheHint von getMenuWithCacheHint(), getSiteSettingsWithCacheHint(), getTaxonomyTermsWithCacheHint() oder getWidgetAreaWithCacheHint() verwenden.
Menü-Tags decken nur Menübearbeitungen ab. Das Veröffentlichen, Zurückziehen, Löschen (in den Papierkorb) oder Wiederherstellen eines Eintrags, auf den ein Menü verlinkt, oder das Ändern des Slugs eines verlinkten Eintrags oder Taxonomiebegriffs invalidiert den Tag des Menüs nicht. Eine Seite, die das Menü anzeigt, übernimmt eine solche Änderung, wenn ihre Tags auch diesen Eintrag, seine Sammlung oder die Taxonomie dieses Begriffs nennen, andernfalls erst, wenn die Seite abläuft.
Das Erstellen, Bearbeiten oder Löschen einer Weiterleitung invalidiert die gecachte Seite am Quellpfad der Weiterleitung, mit und ohne abschließenden Schrägstrich, sodass die Weiterleitung bei der nächsten Anfrage greift.
Das Wiederherstellen einer älteren Revision sowie Änderungen an Autorenzeilen, der Medienbibliothek und Kommentaren invalidieren nichts. Davon betroffene gecachte Seiten werden aktualisiert, sobald sie ablaufen oder der Eintrag, der sie rendert, erneut gespeichert wird. Die zeitgesteuerte Veröffentlichung invalidiert die Tags der veröffentlichten Einträge nur auf Cloudflare; siehe Unterschiede zwischen Providern.
Deshalb ist auch die Tag-Konvention wichtig: EmDash invalidiert Collection-Namen, Eintrags-IDs und die emdash:*-Chrome-Tags. Verwenden Ihre Route-Regeln andere Tag-Namen, greift die integrierte Invalidierung nicht, und veraltete Einträge bleiben bestehen, bis maxAge abläuft.
Antworten aus dem Cache heraushalten
Route-Regeln treffen auf den Anfragepfad zu und gelten daher auch für Antworten, die Sie nicht mit einer langen TTL cachen möchten. EmDash hält Antworten, die für einen angemeldeten Benutzer gerendert wurden, Antworten, die mit Cache-Control: private oder no-store gesendet wurden, sowie 404-Antworten automatisch aus dem Route-Cache heraus. Andere Fehlerantworten und Ihre eigenen Middleware-Weiterleitungen sind Aufgabe des Templates und werden pro Anfrage mit Astro.cache.set(false) ausgenommen.
Astro.cache.set(false) gilt nur bis zum nächsten Aufruf von Astro.cache.set(). Ein Layout wird nach dem Frontmatter der Seite gerendert, daher schaltet ein Layout, das einen Cache-Hint setzt, das Caching für eine Seite wieder ein, die sich ausgenommen hat. Reichen Sie die Ausnahme an das Layout weiter (zum Beispiel als Prop) und überspringen Sie dessen Astro.cache.set()-Aufrufe, wenn sie gesetzt ist.
Vorschau- und Bearbeitungslinks werden automatisch behandelt
Die Middleware von EmDash nimmt diese Antworten selbst vom Route-Cache aus, sodass kein Template-Code nötig ist: Anfragen mit einem ?_preview=-Token (gültig oder nicht, denn diese URLs gelten pro Token, und ein gecachter Entwurf wäre sonst auch nach Ablauf des Tokens weiter erreichbar) sowie Antworten, in die die Editor-Symbolleiste eingefügt wurde. Mit toolbar: "client" gilt dasselbe für ?_edit-URLs. Gültige Vorschau-Antworten und Antworten mit eingefügter Symbolleiste werden zusätzlich für Browser und nachgelagerte CDNs mit Cache-Control: private, no-store markiert.
Fehlerantworten
EmDash hält jede 404-Antwort aus dem Route-Cache heraus, sodass ein später veröffentlichter, zuvor fehlender Eintrag sofort angezeigt wird. Andere Fehlerantworten, etwa ein 500, das auf einer gecachten Route gerendert wird, erben die TTL der Regel. Nehmen Sie sie mit Astro.cache.set(false) aus.
Weiterleitungen in der Middleware
Middleware, die mit einer Weiterleitung kurzschließt (zum Beispiel zur Kanonisierung des Hostnamens), muss sich mit context.cache?.set(false) ausnehmen. Andernfalls wird die Weiterleitung mit der TTL der Route-Regel gecacht, und bei einem CDN-Provider, der Cache-Einträge nicht nach Hostname trennt, kann sie auch an Anfragen für den kanonischen Hostnamen ausgeliefert werden und sofort eine Weiterleitungsschleife verursachen. Verwenden Sie Optional Chaining: context.cache ist bei manchen Antworten undefined, etwa bei der 404-Seite für eine URL, die zu keiner Route passt.
Redakteure und gecachte Seiten
Der Route-Cache speichert pro URL eine gemeinsame Variante, und sein Cache-Schlüssel ignoriert Cookies, sodass ein Cache-Treffer nie die Sitzung eines Redakteurs widerspiegelt. Mit der standardmäßigen serverseitig gerenderten Symbolleiste erhält ein Redakteur, der die öffentliche Site durchstöbert, in der Regel die gecachte anonyme Variante ohne Symbolleiste, und das Cookie emdash-edit-mode hat bei einer gecachten URL keine Wirkung. Eine für einen angemeldeten Redakteur gerenderte Seite wird nie im gemeinsamen Cache gespeichert; der nächste anonyme Besucher befüllt ihn.
Setzen Sie toolbar: "client" für Sites, die Route-Caching verwenden. Ein kleines Skript zeigt dann angemeldeten Redakteuren auf gecachten Seiten die Bearbeiten-Schaltfläche an, und die Bearbeitungsansicht wird über eine ?_edit-URL geladen, die immer frisch gerendert wird. Vorschau-Links umgehen den Cache in beiden Modi.
Unterschiede zwischen Providern
Node.js mit memoryCache()
- Jeder Serverprozess führt seinen eigenen Cache, und eine Invalidierung leert nur den Prozess, der den Schreibvorgang bearbeitet hat. Wenn Sie mehrere Prozesse oder Instanzen betreiben, liefern die anderen ihre gecachten Seiten weiter aus, bis
maxAgeabläuft. - Ein Neustart leert den Cache.
memoryCache()speichert nur Antworten mit einemmaxAge, eine Route ohne Regel wird also nie gecacht, auch wenn die SeiteAstro.cache.set()mit einem Cache-Hint aufruft.- Die zeitgesteuerte Veröffentlichung invalidiert den Route-Cache unter Node nicht. Eine Seite, die einen geplanten Eintrag auflistet, zeigt ihn erst, wenn ihre gecachte Kopie abgelaufen ist. Halten Sie
maxAgedaher bei Routen, die geplante Inhalte auflisten, kurz.
Cloudflare mit cacheCloudflare()
- Der Provider schreibt die Antwort-Header
Cloudflare-CDN-Cache-ControlundCache-Tag. Der Workers Cache wertet beide aus; Clients sehen sie nie, und einCache-Control-Header, den Ihre Seiten für Browser setzen, bleibt unberührt. - Ist ein Cache-Provider konfiguriert, aktiviert der Adapter
@astrojs/cloudflareden Workers Cache automatisch: Der Build schreibt"cache": { "enabled": true }in die generierte Wrangler-Konfiguration, diewrangler deployübernimmt. - Eine Route ohne Regel wird mit
no-storemarkiert, aber nur, wenn während des Renderns nichtsAstro.cache.set()aufruft. Ein Cache-Hint ohnemaxAge, wie ihngetSiteSettingsWithCacheHint()undgetMenuWithCacheHint()liefern, erzeugtCloudflare-CDN-Cache-Control: publicohne Lebensdauer, sodass der Workers Cache auf seine Standard-Cache-Lebensdauern zurückfällt (2 Stunden für eine200-Antwort). Setzt Ihr Layout diese Hints, wird jede Seite, die das Layout verwendet, cachebar, mit oder ohne Regel. - Standardmäßig ist die Worker-Version Teil des Cache-Schlüssels, sodass jedes Deployment mit einem leeren Cache beginnt und die ersten Anfragen danach im Worker gerendert werden. Um Einträge über Deployments hinweg zu behalten, setzen Sie
"cache": { "enabled": true, "cross_version_cache": true }in Ihrer Wrangler-Konfiguration (siehe Versionsübergreifendes Caching). Template-Änderungen werden dann erst sichtbar, wenn die betroffenen Einträge ablaufen oder invalidiert werden. - Die zeitgesteuerte Veröffentlichung invalidiert die Tags der Einträge, die sie über den Cron Trigger veröffentlicht.
Ratenlimits beim Leeren
Der Cloudflare-Provider invalidiert, indem er den Workers Cache leert. Das Leeren des Workers Cache unterliegt immer den Purge-Limits des Free-Tarifs von Cloudflare, unabhängig vom Tarif Ihres Kontos: 5 Anfragen pro Minute mit einem Burst von 25, pro Konto (siehe Ratenlimits beim Leeren). Die meisten Schreibvorgänge an Inhalten kosten jeweils eine Purge-Anfrage: Speichervorgänge, die Live-Inhalte ändern (einschließlich Autosaves in Collections, die direkt in den Live-Eintrag speichern), Veröffentlichen, Zurückziehen, Löschen, Wiederherstellen, Planen und das Zuweisen von Taxonomie-Begriffen zu einem Eintrag, dazu jede Bearbeitung von Einstellungen, Menüs, Taxonomien oder Widgets. Das Schreiben einer Weiterleitung kostet eine Purge-Anfrage pro Variante des Quellpfads, also bis zu vier, wenn sich die Quelle einer Weiterleitung ändert.
Ein durch das Ratenlimit abgelehntes Leeren schlägt ohne Fehlermeldung im Admin-Bereich fehl, und die betroffenen Seiten behalten ihre gecachte Version, bis maxAge abläuft. Wählen Sie bei Massenbearbeitungen oder wenn mehrere Redakteure gleichzeitig arbeiten ein maxAge, das Sie im schlimmsten Fall für veraltete Inhalte akzeptieren können.
Browser-Caching ist getrennt
Der Route-Cache kann sich lange TTLs leisten, weil EmDash ihn invalidiert; Browser-Caches werden nicht invalidiert. Die Hints von EmDash liefern Purge-Tags, aber keine automatischen Last-Modified-Validatoren und auch nicht den impliziten Header Cache-Control: no-cache von Astro. Die Änderungszeit eines einzelnen Eintrags deckt weder Einstellungen noch verwandte Listen oder gelöschte Einträge ab. Verwenden Sie sie als Validator für eine Seite, kann daher ein veralteter Body über bedingte 304-Antworten erhalten bleiben.
Steuern Sie das Browser-Caching mit Astro.response.headers.set("Cache-Control", ...): Verwenden Sie no-cache für eine frische Prüfung bei jedem Besuch oder eine kurze Lebensdauer (Minuten, nicht Tage). Um bedingte Anfragen zu ermöglichen, liefern Sie einen eigenen lastModified-Hint, dessen Zeitstempel fortschreitet, sobald sich irgendeine Abhängigkeit der Antwort ändert.
Für das angezeigte Änderungsdatum eines Eintrags verwenden Sie entry.data.updatedAt statt cacheHint.lastModified, das EmDash nicht automatisch befüllt.