Was ohne Cache bei jedem Aufruf passiert
WordPress ist ein dynamisches System. Es gibt keine fertigen HTML-Dateien, die der Server einfach verschicken könnte. Jede Seite entsteht erst in dem Moment, in dem jemand sie aufruft.
Ohne Cache läuft dabei jedes Mal derselbe Ablauf: Der Webserver übergibt die Anfrage an PHP. PHP lädt den WordPress-Kern, alle aktiven Plugins und das Theme. WordPress fragt die Datenbank nach Inhalten, Menüs, Einstellungen und Widgets ab und setzt daraus die Seite zusammen. Erst danach erhält der Besucher das erste Byte HTML.
Für zehn Besucher passiert das zehnmal, obwohl alle exakt dieselbe Seite bekommen. Genau hier setzt Caching an: Ergebnisse, die sich nicht geändert haben, werden einmal erzeugt, gespeichert und danach wiederverwendet. Das geschieht auf mehreren Ebenen, die unterschiedliche Teile dieser Arbeit einsparen.
Browser-Cache: Dateien nicht doppelt laden
Die erste Ebene liegt beim Besucher selbst. Eine Webseite besteht neben dem HTML aus vielen weiteren Dateien wie CSS, JavaScript, Schriften und Bildern. Der Browser kann diese Dateien speichern und beim nächsten Seitenaufruf wiederverwenden, statt sie erneut herunterzuladen.
Wie lange er das darf, legt der Server über den HTTP-Header Cache-Control fest. Mit max-age gibt er an, wie viele Sekunden eine Datei als aktuell gilt. Die Angabe immutable sagt zusätzlich, dass sich die Datei in dieser Zeit nicht ändert:
Cache-Control: public, max-age=31536000, immutable Diese Header kommen vom Webserver, nicht von WordPress. Statische Dateien wie Bilder oder CSS liefert der Webserver direkt aus, ohne PHP. Ein Cache-Plugin hat darauf deshalb in der Regel keinen Einfluss. Bei Nginx stehen die Regeln in der Serverkonfiguration, bei Apache können sie auch in der Datei .htaccess hinterlegt sein.
Damit Besucher nach einem Update trotzdem die neue Version erhalten, hängt WordPress an eingebundene CSS- und JavaScript-Dateien eine Versionsnummer an, zum Beispiel style.css?ver=1.4.2. Ändert sich die Version, ändert sich die Adresse, und der Browser lädt die Datei neu.
Auch das HTML selbst kann der Browser zwischenspeichern. Ruft ein Besucher eine Seite erneut auf, fragt der Browser beim Server nach, ob sich seine gespeicherte Version geändert hat. Ist das nicht der Fall, antwortet der Server nur mit dem Statuscode 304 Not Modified und schickt keinen Inhalt mit. Die Seite kommt dann vollständig aus dem Browser. Bei wpinabox nutzen wir das für gecachte HTML-Seiten.
Object-Cache: Datenbankabfragen zwischenspeichern
WordPress bringt bereits einen eigenen Object-Cache mit. Er speichert Ergebnisse von Datenbankabfragen und andere berechnete Daten, damit dieselbe Abfrage innerhalb eines Seitenaufrufs nicht mehrfach ausgeführt wird. Die WordPress-Dokumentation sagt dazu: Der Object-Cache ist standardmäßig nicht persistent. Die Daten liegen nur im Arbeitsspeicher und nur für die Dauer der jeweiligen Anfrage.
Davon zu unterscheiden sind die Transients. Das ist eine eigene Schnittstelle, mit der Plugins Daten für eine bestimmte Zeit speichern, zum Beispiel das Ergebnis einer externen Abfrage. Ohne persistenten Object-Cache legt WordPress Transients in der Datenbank ab, in der Tabelle wp_options. Mit persistentem Object-Cache landen sie stattdessen im schnellen Arbeitsspeicher.
Ein persistenter Object-Cache speichert die Daten über den einzelnen Aufruf hinaus, sodass auch der nächste Besucher davon profitiert. Technisch funktioniert das über ein sogenanntes Drop-in. Das ist eine Datei mit festem Namen, die WordPress an einer festen Stelle sucht und automatisch lädt. Für den Object-Cache ist das die Datei object-cache.php im Ordner wp-content. Existiert sie, ersetzt sie den eingebauten Cache durch ein externes Speichersystem. Weil es nur eine solche Datei geben kann, ist auch immer nur ein persistenter Object-Cache aktiv.
SQLite, Redis oder APCu im Vergleich
Welches Speichersystem hinter dem Drop-in steckt, entscheidet über die Geschwindigkeit. Für WordPress gibt es drei verbreitete Varianten.
SQLite speichert die Cache-Einträge in einer Datei auf dem Server. Das Plugin SQLite Object Cache legt dafür eine Datei .ht.object-cache.sqlite im Ordner wp-content an. Diese Lösung richtet sich laut Plugin-Beschreibung an Webseiten auf einem einzelnen Server, deren Hoster weder Redis noch Memcached anbietet. Ist APCu verfügbar, beschleunigt das Plugin den Zugriff zusätzlich damit.
Redis ist ein eigenständiger Datenbankdienst, der Daten im Arbeitsspeicher hält. Er läuft als separater Prozess, auf demselben oder auf einem anderen Server. Angebunden wird er zum Beispiel über das Plugin Redis Object Cache. Jeder Zugriff aus WordPress geht dabei über eine Netzwerkverbindung zu diesem Dienst.
APCu ist ein Schlüssel-Wert-Speicher im Arbeitsspeicher, der direkt in PHP integriert ist. Es gibt keinen separaten Dienst und keine Verbindung. Die Daten liegen im gemeinsamen Arbeitsspeicher der PHP-Prozesse.
| SQLite | Redis | APCu | |
|---|---|---|---|
| Speicher | Datei | Arbeitsspeicher | Arbeitsspeicher |
| Zugriff | Dateisystem | Netzwerk (TCP) | direkt in PHP |
| Eigener Dienst | nein | ja | nein |
| Mehrere Server | nein | ja | nein |
Warum APCu auf einem Server am schnellsten ist
Der Unterschied liegt im Weg zu den Daten. Mit Redis geht jeder Zugriff über eine Netzwerkverbindung zu einem anderen Prozess. Das verbreitete Plugin Redis Object Cache verbindet sich standardmäßig per TCP mit 127.0.0.1, also auch dann über den Netzwerk-Stack, wenn Redis auf demselben Server läuft. Einige Hoster nutzen stattdessen einen Unix-Socket, auch das bleibt aber eine Verbindung zu einem fremden Prozess. Mit APCu liest PHP die Daten direkt aus dem eigenen Arbeitsspeicher.
Wie groß dieser Unterschied ist, zeigt ein Benchmark von AltumCode auf einem Server mit PHP 8.4 und Redis über TCP auf 127.0.0.1: Beim Lesen von 1-KB-Einträgen schaffte Redis rund 22.000 Zugriffe pro Sekunde, APCu über 6,4 Millionen. Ein Test von Clypper Technology mit WordPress und WooCommerce kommt zu einem ähnlichen Bild: Bei 50 gleichzeitigen Nutzern steigerte APCu den Durchsatz gegenüber einer Installation ohne Object-Cache um rund 23 %, Redis um rund 4 %. Wie stark sich das auf die Ladezeit auswirkt, hängt davon ab, wie viele Cache-Zugriffe eine Seite braucht.
Seine Stärke spielt Redis aus, wenn mehrere Server denselben Cache teilen müssen. WordPress läuft in aller Regel auf einem einzelnen Server, und dort ist APCu die schnellste Lösung. Weil der Speicher zu PHP gehört, ist er nach einem Neustart von PHP leer und füllt sich mit den nächsten Aufrufen wieder. Außerdem nutzt WP-CLI laut PHP-Handbuch standardmäßig kein APCu, den Object-Cache leerst du deshalb über WordPress selbst.
Bei wpinabox ist der APCu Object-Cache in jedem Tarif enthalten. Am meisten profitieren Seiten, bei denen viele Aufrufe dynamisch entstehen, etwa Online-Shops und Mitgliederbereiche. Kommt eine Seite fast vollständig aus dem Page-Cache, fällt der Unterschied kleiner aus.
Page-Cache: So arbeitet ein Cache-Plugin
Der Object-Cache spart Datenbankabfragen, aber WordPress muss die Seite trotzdem noch zusammensetzen. Der Page-Cache geht einen Schritt weiter: Er speichert die komplett fertige HTML-Seite und liefert sie beim nächsten Aufruf direkt aus.
Auch das funktioniert über ein Drop-in. Ein Cache-Plugin legt die Datei advanced-cache.php im Ordner wp-content an und setzt in der wp-config.php die folgende Konstante:
define( 'WP_CACHE', true ); Ist WP_CACHE aktiv, lädt WordPress die Datei advanced-cache.php sehr früh. Im Quellcode der Datei wp-settings.php passiert das, bevor der Object-Cache startet, bevor die Plugins geladen werden und bevor das Theme an der Reihe ist. Findet das Drop-in eine passende gespeicherte Seite, gibt es sie in der Regel sofort aus und beendet die Verarbeitung. Plugins, Theme und Datenbank bleiben unberührt.
Deshalb macht ein Cache-Plugin eine Webseite so deutlich schneller. Ein Rest bleibt allerdings: Damit das Drop-in überhaupt laufen kann, muss der Webserver die Anfrage zuerst an PHP übergeben, und PHP muss die ersten Dateien von WordPress laden. Auch eine gecachte Seite kostet so noch PHP-Arbeit.
Ohne Cachejede Seite neu
Cache-PluginPHP startet noch
PowerCacheohne PHP
PowerCache: Seiten ausliefern ohne PHP
Mit PowerCache setzen wir genau an diesem Rest an. Das Cache-Plugin speichert die fertige Seite wie gewohnt als Datei. Die Serverkonfiguration von PowerCache sorgt dafür, dass Nginx diese Datei selbst erkennt und direkt ausliefert. Die Anfrage erreicht PHP gar nicht erst, und auch das Drop-in muss nicht mehr laufen.
Für Besucher heißt das: Die Antwort kommt direkt vom Webserver, ohne dass PHP die Anfrage überhaupt bearbeitet. Für den Server heißt das: Gecachte Seiten kosten kaum noch Rechenleistung. PHP bleibt frei für die Anfragen, die wirklich dynamisch sein müssen. Davon profitiert die Webseite vor allem bei vielen gleichzeitigen Besuchern.
Ein ähnlicher serverseitiger Ansatz ist der FastCGI-Cache von Nginx. Bei der Geschwindigkeit liegen beide Varianten auf gleichem Niveau. Der Unterschied liegt in der Bedienung: Beim FastCGI-Cache werden Regeln und Ausnahmen direkt in der Serverkonfiguration festgelegt, bei PowerCache steuerst du alles über die Einstellungen deines Cache-Plugins.
PowerCache arbeitet mit unserem eigenen Plugin WP:BOX Cache, das bei jeder Installation vorinstalliert ist, und mit WP Rocket zusammen. Das System erkennt das aktive Cache-Plugin automatisch, nach einer Aktivierung oder einem Wechsel dauert die Umstellung bis zu 20 Minuten. Besucher mit Desktop und Smartphone erhalten dabei jeweils die passende gecachte Version, ohne dass du etwas einstellen musst. Andere Cache-Plugins funktionieren ebenfalls, nutzen dann aber nur den klassischen Weg über PHP.
Wann der Cache umgangen wird
Nicht jede Seite darf aus dem Page-Cache kommen. Sobald der Inhalt für einen bestimmten Besucher anders aussieht, muss WordPress ihn neu erzeugen. Sonst würde ein Besucher zum Beispiel den Warenkorb eines anderen sehen. Bei wpinabox entstehen deshalb diese Seiten immer dynamisch:
- alle Seiten für angemeldete Benutzer
- Seiten für Besucher, die Artikel im Warenkorb haben
- Warenkorb, Kasse und Kundenkonto in WooCommerce
- passwortgeschützte Seiten
- Formularabsendungen und Adressen mit Parametern, etwa Such- oder Filterergebnisse
Genau bei diesen Seiten zeigt der Object-Cache seinen Wert. Wenn PHP doch arbeiten muss, kommen häufig benötigte Daten aus dem Arbeitsspeicher statt aus der Datenbank. Page-Cache und Object-Cache ergänzen sich also: Der eine beschleunigt alles, was für alle gleich ist, der andere alles, was individuell bleiben muss.
Häufige Fragen
Brauche ich bei wpinabox ein eigenes Cache-Plugin?
Nein. Unser Plugin WP:BOX Cache ist bereits vorinstalliert und auf PowerCache abgestimmt. Alternativ wird WP Rocket unterstützt. Andere Cache-Plugins funktionieren auch, nutzen aber nicht den PowerCache. Wichtig ist, dass immer nur ein Cache-Plugin aktiv ist.
Kann ich Redis und APCu gleichzeitig nutzen?
Nein. Der persistente Object-Cache läuft über die eine Datei object-cache.php im Ordner wp-content. Es kann also immer nur ein Speichersystem aktiv sein. Auf einem einzelnen Server ist APCu dabei die schnellere Wahl.
Macht ein Object-Cache jede Webseite schneller?
Nicht im gleichen Maß. Am stärksten profitieren Shops, Mitgliederbereiche und Seiten mit vielen angemeldeten Nutzern. Kommt eine Seite fast vollständig aus dem Page-Cache, fallen ohnehin kaum Datenbankabfragen an.
Warum sehe ich eine Änderung nicht sofort?
Meist liefert der Page-Cache noch die gespeicherte Version aus, oder dein Browser zeigt eine Datei aus seinem eigenen Cache. Leere den Cache im Cache-Plugin und lade die Seite im Browser neu.
Quellen
- WordPress Developer Reference: WP_Object_Cache
- WordPress Developer Resources: Transients API
- WordPress Developer Reference: _get_dropins()
- WordPress-Quellcode: wp-settings.php
- MDN Web Docs: Cache-Control
- MDN Web Docs: 304 Not Modified
- PHP-Handbuch: APCu-Konfiguration
- Redis Object Cache: Installationsanleitung
- WordPress.org: SQLite Object Cache
- AltumCode: APCu vs Redis vs File Cache, Benchmark
- Clypper Technology: WordPress Object Cache Showdown
- SpinupWP: Top 3 WordPress Cache Plugins and How to Turbocharge Them with Nginx