Eine Seite kann blitzschnell ausgeliefert werden und sich trotzdem zäh anfühlen. Genau dieses Paradox begegnet uns regelmäßig bei modernen WordPress-Sites – und die Ursache ist fast immer dieselbe: dynamische Inhalte werden per JavaScript aus einem ungecachten API-Endpoint nachgeladen. Dieser Beitrag zeigt, woran man das erkennt und wie ein kleiner Micro-Cache mit einem besonders eleganten Invalidierungs-Trick das Problem löst.
Das Paradox: HTML in 0,16 s, gefühlt aber 5 Sekunden
Ein typischer Befund aus der Praxis: Das HTML einer Seite kommt aus dem Page-Cache (Varnish/LiteSpeed) mit einem TTFB von ~0,16 Sekunden – traumhaft. Trotzdem berichten Besucher, die Seite „ruckelt“ oder „baut sich langsam auf“.
Der Grund: Das ausgelieferte HTML enthält die dynamischen Bereiche (z. B. Team-Fotos, Blog-Teaser, Logo-Slider) noch gar nicht – dort stehen leere Container. Erst im Browser fragt JavaScript per fetch() die Daten nach:
fetch('/wp-json/wp/v2/team_member?per_page=30&_fields=id,title,link')
.then(r => r.json())
.then(renderGrid);
Und genau diese Nachfrage ist der Flaschenhals.
Der blinde Fleck: /wp-json/ ist vom Cache ausgenommen
Page-Caches liefern HTML-Seiten aus dem Speicher – die REST-API dagegen wird fast überall bewusst vom Caching ausgeschlossen, weil sie auch für Schreibvorgänge und personalisierte Daten zuständig ist. Im Response-Header sieht das so aus:
x-cacheable: NO:URL:WP-JSON
x-varnish-cache: BYPASS
cache-control: no-store, no-cache, must-revalidate
Heißt: Jeder einzelne Seitenaufruf löst eine frische, ungecachte Datenbankabfrage im WordPress-Backend aus. Bei verschachtelten Abfragen, vielen aktiven Plugins oder einem mehrsprachigen Setup dauert das schnell 3 bis 8 Sekunden. Die HTML-Seite ist längst da – aber die Fotos und Cards „poppen“ erst Sekunden später rein. Das ist die gefühlte Langsamkeit.
Die Lösung: ein Micro-Cache vor den Lese-Endpoints
Lese-Endpoints (GET) für öffentliche Inhalte müssen nicht in Echtzeit sein. Ein kurzer serverseitiger Cache vor diesen Routen senkt die Antwortzeit von mehreren Sekunden auf ~50 Millisekunden – ohne eine einzige Zeile im Frontend zu ändern. Das vorhandene fetch() bleibt, es bekommt seine Daten nur sofort.
In WordPress lässt sich das sauber an zwei Filtern einklinken:
rest_pre_dispatch– fängt den Request vor der teuren Query ab und liefert bei einem Cache-Treffer direkt die gespeicherte Antwort.rest_pre_echo_response– greift die fertige Payload ab (inklusive_fields-Filter und_embed) und legt sie bei einem Cache-Miss ab.
Wichtig dabei: Nur anonyme GET-Requests werden gecacht. Eingeloggte Redakteure und der Gutenberg-Editor bekommen immer frische Daten – sonst würde man im Backend veraltete Inhalte sehen.
Das elegante Stück: Auto-Purge per „Versions-Bump“
Die spannendste Frage bei jedem Cache lautet: Wann wird er ungültig? Ein fester Timer (z. B. 10 Minuten) ist ein Sicherheitsnetz – aber er bedeutet auch, dass ein frisch veröffentlichter Blogbeitrag bis zu 10 Minuten unsichtbar bleibt.
Viel schöner ist ereignisgesteuerte Invalidierung beim Speichern. Der klassische Weg – beim Speichern jeden betroffenen Cache-Key einzeln suchen und löschen – ist fehleranfällig, weil die Keys von Query-Parametern abhängen (per_page, _fields, page …).
Der Trick: Man baut eine Cache-Versionsnummer in jeden Key ein und erhöht beim Speichern einfach diese eine Nummer. Damit zeigen alle alten Keys ins Leere – der gesamte Cache ist in einer einzigen, atomaren Operation entwertet, ohne dass man auch nur einen einzelnen Eintrag kennen muss:
// Versionsnummer in den Key einweben
function cache_key($request) {
$ver = (int) get_option('restc_ver', 1);
$params = $request->get_query_params();
ksort($params);
return 'restc_' . $ver . '_' . md5($request->get_route() . wp_json_encode($params));
}
// Beim Speichern: Version hochzählen → ALLE Keys sofort ungültig
add_action('save_post', function () {
update_option('restc_ver', ((int) get_option('restc_ver', 1)) + 1);
});
Die alten Transients verschwinden danach von selbst, sobald ihr Timer abläuft. Das Ergebnis: Inhalte sind beim Speichern sofort aktuell, und der Backend wird trotzdem entlastet. Dasselbe Muster („generation counter“ oder „cache busting via version“) nutzen auch große CDNs und Frameworks – es ist robust, lock-frei und braucht keine Liste aller Keys.
Wann lieber Server-Side Rendering (SSR)?
Caching behebt das Tempo, aber der Inhalt wird weiterhin per JavaScript nachgeladen. Für die meisten Widgets (Slider, Team-Grid, Teaser) ist das völlig ausreichend. In zwei Fällen lohnt der Schritt zum echten Server-Side-Rendering, bei dem der Inhalt direkt ins HTML gerendert wird:
- SEO: Soll der Inhalt zuverlässig indexiert werden, gehört er ins initiale HTML – nicht erst per JS nachgeladen.
- Kein „Pop-in“: Wenn schon der erste Frame perfekt sitzen soll (Layout-Stabilität, Core Web Vitals / CLS), rendert man serverseitig vor.
Die Praxis-Faustregel: Caching zuerst – es bringt 95 % des Tempogewinns bei minimalem Risiko und ohne Eingriff in bestehende, handgetunte Komponenten. SSR ist die Kür für die Fälle, in denen es wirklich darauf ankommt.
Die wichtigsten Erkenntnisse
- Ein guter Page-Cache (niedriger TTFB) sagt nichts über die gefühlte Geschwindigkeit aus, wenn Inhalte per JS aus ungecachten APIs nachgeladen werden.
/wp-json/ist standardmäßig vom Caching ausgenommen – jeder Aufruf trifft das rohe Backend.- Ein Micro-Cache (10 Min) für anonyme GET-Reads senkt 3–8 s auf ~50 ms – ohne Frontend-Änderung.
- Cache-Invalidierung per Versions-Bump beim Speichern macht Inhalte sofort aktuell und ist deutlich robuster als das Löschen einzelner Keys.
- SSR ist der nächste Schritt für SEO und maximale Layout-Stabilität – aber Caching kommt zuerst.
Fragen zu Performance-Optimierung, Core Web Vitals oder einer trägen WordPress-Site? Das Team von OIT hilft gerne weiter.
Hast du eine Frage zu diesem Artikel?
Schreib uns – wir antworten in der Regel innerhalb eines Werktages.
Ähnliche Artikel
Langsame Unterseiten bei Raidboxes? Warum s-maxage im Varnish-Cache der wahre Hebel ist
Viele WordPress-Seiten bei Raidboxes laufen blitzschnell – bis ein SEO-Tool wie Semrush plötzlich D…
Lesen →
GEO-Checkliste: So wird deine WordPress-Website sichtbar in ChatGPT & Co.
Das Wichtigste in Kürze: GEO (Generative Engine Optimization) sorgt dafür, dass deine Website von K…
Lesen →
Google reCAPTCHA – neuer Name: Was sich für eure Website ändert
Google hat zum 23. April 2026 eine seiner bekanntesten Sicherheitslösungen umbenannt und in eine gr…
Lesen →