Caching: Was ist was?

Geschwindigkeit ist wichtig, und Geschwindigkeit erreicht man in CMS wie WordPress über Caching- so die landläufige Meinung. Aber was ist das eigentlich, dieses Caching? Mittlerweile werden mit dem Begriff eine ganze Reihe an Techniken bezeichnet, die sich zum Teil deutlich unterscheiden. Und nicht für alles braucht man ein Plugin.

Was bedeutet Caching?

Caching ist an sich erst einmal das Zwischenspeichern von Informationen, die mehrfach genutzt werden. Dadurch spart man Ressourcen: Dateien müssen nicht nochmal übertragen werden, Daten müssen nicht nochmal generiert werden, … etc – und das spart am Ende Serverressourcen und Zeit. Caching kann an verschiedenen Stellen stattfinden, an verschiedenen Punkten auf dem Server und natürlich im Client, also im Browser. Mittlerweile werden auch Mechanismen in Caching-Plugins angeboten, die eigentlich kein Caching sind, auf diese wird am Ende auch kurz eingegangen.

Seitenausgabe-Caching

Dies ist die schärfste Waffe, die man als Admin hat, um ein WordPress performant wirken zu lassen, und meistens ist es auch das, was unter „Caching“ erst einmal verstanden wird. Um Seitenausgabe-Caching zu verstehen, schauen wir uns mal an, wie ein Abruf einer Seite funktioniert:

Seitenabruf ohne Caching

Wenn nun der generierte Inhalt für alle Menschen gleich ist, dann wäre es ja überflüssige Arbeit, die komplette Seite jedes mal neu zu generieren. Man speichert also die fertig zusammengestellte Seite zwischen – in einem Seitenausgabe-Cache:

Seitenabruf mit Caching

Es gibt drei verschiedene Varianten, den Cache auszuliefern: über PHP (so arbeiten die meisten Caching-Plugins), über die htaccess (so arbeitet WP SuperCache, wenn man es richtig einstellt) und über Serverdienste wie Nginx FCGI Caching oder Varnish. PHP ist am langsamsten, Serverdienste am schnellsten.

Natürlich muss der Cache erst einmal befüllt werden. Dies geschieht entweder durch einen Nutzer, der das erste Mal auf die Seite kommt, oder aber durch ein sogenanntes Prefilling. Überlässt man dies dem Nutzer, so haben einige wenige Nutzer eine eher lange Ladezeit, weil sie den Cache füllen, alle danach kommenden Nutzer bekommen dann die schnelle, gecachte Ausgabe.

Wenn man die Seite aktualisiert hat, muss ein Cache gepurged werden – schließlich möchte man ja, dann zB. der neu geschrieben Artikel dann auf der Startseite auch erscheint und nicht weiterhin die alte Startseite ausgeliefert wird. Die meisten Caching-Plugins haben so einen Cache-Purging-Mechanismus mit drin, lediglich bei den besonders schnellen Serverdienst-Cachings über Nginx FCGI Cachin oder Varnish muss man sich darüber intensivere Gedanken machen. Allerdings funktioniert das Cache-Purging der Plugins nur, wenn man etwas an einer Seite, einem Beitrag oder Ähnlichem ändert – wenn man dagegen etwas globales z.B. an den Theme-Einstellungen ändert, dann muss man manuell den Cache purgen. Die allermeisten Caching-Plugins bieten das in ihren Einstellungen an.

Seitenausgabe-Caching ist natürlich nur dann machbar, wenn viele Nutzer dieselbe Ausgabe bekommen. Kurzum: nach einem Login ist ein Ausgabe-Caching typischerweise nicht mehr aktiv, da dann die ausgelieferte Website ja um Informationen angereichert wird, die nur den eingeloggten Nutzer betreffen. Erkennbar sind solche nutzerspezifischen Seiten-Auslieferungen an Cookies. Mit anderen Worten: wird ein Cookie gesetzt, ist das Caching gebrochen. Ob Cookies gesetzt werden, kann man gut mit Pingdom nachvollziehen:

Die von WPML gespiegelten Cookies brechen das Seitenausgabe-Caching.

Das gezeigte Beispiel ist übrigens ein sehr Schönes, weil es zeigt, wie durch unsaubere Programmierung Caching gebrochen wird. WPML setzt die Sprache nicht nur über die URL, sondern auch über ein Cookie, woraufhin das Caching-System denkt, dass es sich hierbei um eine nutzerangepasste Seite handelt, und sich selbst abschaltet. Dabei tut das schlicht nicht not. Manch ein Caching-Plugin korrigiert diese Programmierfehler dann, indem es die WPML Cookies ignoriert – aber am Ende ist das ein dreckiger, nachträglicher Bugfix für eine unsaubere Programmierung der WPML-Autoren.

WooCommerce dagegen ist übrigens ein schönes Beispiel, wie man dynamische Inhalte wie den nur für einen Nutzer geltenden Warenkorb mit Seitenausgabe-Caching kombinieren kann. Die Produkt-Seiten zum Beispiel sehen für alle Menschen in weiten Teilen identisch aus, und so werden all diese Teile gecached. Um die dynamischen Inhalte wie den Warenkorb in die Seite zu bekommen, werden diese dynamisch nachgeladen. Erst, wenn es zum Checkout kommt, deaktiviert WooCommerce das Seitenausgabe-Caching.

WordPress Plugin-Empfehlung: WP SuperCache und Caching via htaccess, Nginx FCGI-Caching mit Nginx Helper beim Root-Server.

Object-Caching

Object-Caching ist ein Caching-Mechanismus innerhalb von PHP. Er basiert darauf, dass einige Informationsfragmente identisch bleiben und nicht bei jeder Anfrage neu generiert werden müssen. Typische Beispiele sind die Theme-Optionen oder die Nutzer-Informationen: diese bleiben üblicherweise über einen längeren Zeitraum identisch und können so zwischengespeichert werden.

Object Caching

Als Zwischenspeicher kann man auf verschiedene Systeme zurückgreifen. Für gut betreute Managed Server ist Redis oder Memcached sicherlich eine Option, aber auch der interne Object Cache von PHP (der dann wiederum Dateien oder auch den Arbeitsspeicher als Speicherort nutzt) ist eine gute Option.

Object Caching ist dann eine gute Wahl, wenn man Features hat, die vom Seitenausgabe-Caching nicht weggecached werden können. Dies ist z.B. bei Shops der Fall, ebenso wie bei jeder Website mit Login. Aber Achtung: schlecht programmierte Plugins, die z.B. bei jedem Aufruf den Cache leeren, können einen Object Cache die Seite auch verlangsamen lassen. Wieder einmal ist die Code-Qualität wichtig.

WordPress Plugin-Empfehlungen: Redis Cache beim Managed- / Root-Server.

Datenbank-Query-Caching

Datenbank-Query-Caching setzt ein wenig vor einem Object-Caching an und speichert komplizierte Anfragen an die Datenbank zwischen. Am Ende ist dies aber aus zwei Gründen wenig sinnvoll:

  1. Ein Datenbankquery sagt erst einmal nichts über die Struktur der Daten aus. Um Daten effizient zu speichern, müssen also die PHP-Objekte mit ihrer konkreten Datenstruktur gecached werden, nicht die Datenbank-Queries. Datenbank-Query-Caching in einem Caching-Plugin ist letztlich also eher poor-mans-Object-Caching.
  2. Die richtige Stelle für ein Datenbank-Query-Caching wäre die Datenbank selbst. Dort kann ein Systemadministrator einstellen, wie viel Arbeitsspeicher dem Caching zur Verfügung steht. Dies geschieht erheblich intelligenter und schneller, als es ein Caching-Plugin je machen könnte. Dies kann von Webspace-Nutzern aber nicht geändert werden, da falsche Einstellungen dort schnell zu erheblichem RAM-Verbrauch und so zu Serverabstürzen führen.

Insgesamt kann man von Datenbank-Query-Caching in einem Plugin also nur abraten.

Browser-Caching

Wenn man mehr als eine Unterseite auf einer Website aufruft, werden oft dieselben Dateien wieder und wieder verwendet. Ein Logo im Seitenkopf ist dafür ein gutes Beispiel, ebenso aber auch CSS- und JS-Dateien. Es macht also Sinn, diese Dateien im Browser zwischenzuspeichern und nicht jedes mal neu zu laden. Dies geschieht durch das Browser-Caching.

Technisch funktioniert das so, dass mit dem immer mitgesendeten HTTP Header mitgeteilt wird, wie lange die Datei gültig bleibt. Diese Gültigkeit setzt man für statische Dateien sehr, sehr lange. Dies geschieht über die Header-Felder Expires oder Cache-Control max-age. Die Steuerung darüber ist verhältnismäßig simpel: der Browser fragt erst dann die Datei wieder an, wenn der angegebene Zeitpunkt vorbei ist.

Alternativ arbeitet man mit einem E-Tag bzw. Last-Modified, welches sich ändert, sobald sich die dazugehörige Datei ändert. Wenn der Browser dann eine Datei bei sich lokal im Cache hat, sendet er einfach das dazu passende E-Tag mit. Der Webserver schaut dann, ob das E-Tag der auf dem Server befindlichen Datei identisch ist. Wenn das der Fall ist, sendet er statt der gesamte Datei nur den Code 304 zurück, der sagt, dass sich die Datei nicht geändert hat. Ein Status-Code ist logischerweise deutlich kleiner als eine ganze CSS- oder Bild-Datei, so dass eine Menge Abfragen eingespart wird. E-Tags haben den Vorteil, dass sie Änderungen auf Serverseite mitbekommen, dies tut eine pauschale sehr lange Caching-Zeit nicht.

Browser-Caching in allen Varianten (und damit doppelten Informationen).

Manchmal möchte man aber den Browser-Cache brechen, z.B., wenn man eine Plugin-Update macht und so neue CSS- und JS-Dateien hineinkommen. Daher hat WordPress die Versionierung über ?ver=1.2.3 eingeführt (auch genannt: Query Strings, schön sichtbar an der style.css oben). Ändert man die Versionsnummer, lädt der Browser die Datei neu und bekommt so von den Änderungen etwas mit.

Es ist im Übrigen gefährlich, der Empfehlung von manchen Analyse-Tools zu folgen, und die Query-Strings zu entfernen. Dann bekommt der Browser nämlich nie mit, dass es eine Änderung in der JavaScript-Datei gab. JavaScript und HTML passen dann ab und an nicht mehr zusammen, und die Website funktioniert nur noch fehlerhaft. Das sollte man vermeiden und so dringend die Query-Strings beibehalten.

Das Browser-Caching wird komplett in der htaccess oder der vHost-Konfiguration eingestellt, da die HTTP-Header vom Webserver (Apache, Nginx, …) erstellt werden. Die meisten Caching-Plugins bieten an, die htaccess entsprechend zu aktualisieren. Wirklich notwendig ist das allerdings nicht, man kann die entsprechenden Zeilen auch einfach per Hand in die htaccess hineinkopieren (dann versteht man auch besser, was da passiert).

Plugin-Empfehlungen: keine, Realisierung via htaccess.

GZIP-Komprimierung

Dies ist kein Caching, wird aber in vielen Caching-Plugins mit angeboten.

Komprimierte Dateien sind kleiner als unkomprimierte Dateien – das kennt jeder von seinem Desktop-Rechner und dort verbreiteten ZIP-Dateien. Derselbe Mechanismus wird auch bei Webservern angewendet. Dabei muss darauf geachtet werden, dass nur Texte (also HTML, CSS, JavaScript) komprimiert werden. Bilder müssen nicht mehr komprimiert werden, da PNG oder JPEG schon stark optimiert sind und keine Vorteile durch eine weitere Kompression erhalten.

Die GZIP-Kompression geschieht bei dem Webserver selbst, also bei Apache oder Nginx, nicht in einem WordPress-Plugin. Wie beim Browser-Caching auch wird GZIP daher auch via htaccess oder via vHost Konfiguration eingeschaltet, und auch der Satz in Bezug auf die Caching-Plugins gilt für GZIP.

Plugin-Empfehlungen: keine, Realisierung via htaccess.

Zusammenfassen von CSS- und JS-Dateien

Dies ist kein Caching, wird aber in vielen Caching-Plugins mit angeboten.

Wenn man viele Themes und Plugins einsetzt, hat man oft eine bemerkenswerte Menge an CSS- und JavaScript-Dateien, die von Theme und Plugins geladen werden. Jede einzelne dieser Dateien muss vom Browser beim Webserver angefragt werden, so dass es sich oft lohnt, die Dateien zusammenzufassen. Dies geschieht über WordPress-Plugins wie z.B. Autoptimize, welche die ganzen Dateien zusammensammeln und dann zusammenfassen.

Doch Achtung – das ist nicht ohne Gefahr. Ein Zusammenfassen der CSS-Dateien ist meist recht gefahrlos. Ein Zusammenfassen der JavaScript-Dateien kann bei schlechter Programmierung von Theme oder Plugins kritische JavaScript-Fehler hervorrufen. Es ist elementar, dass man nach dem Anschalten der JavaScript-Zusammenfassung mit den Developer-Tools des Browsers nach eben solchen Fehlern sucht, ansonsten ist es möglich, dass manche Nutzer eine nicht funktionierende Seite bekommen. Das Zusammenfassen von JavaScript-Dateien kann ich also nur Menschen mit einer Grundkenntnis in JavaScript und JavaScript-Debugging empfehlen, während das Zusammenfassen von CSS-Dateien auch Anfänger durchführen können.

Plugin-Empfehlungen: Autoptimize.

Komprimieren von CSS, JS und HTML

Dies ist kein Caching, wird aber in vielen Caching-Plugins mit angeboten.

Wenn man als Entwickler CSS-, JavaScript oder HTML schreibt, dann macht man häufiger mal Leerzeichen oder Einrückungen, um den Code gut lesbar zu halten. Ebenso macht man bestenfalls viele Kommentare, damit man den Code schnell versteht. So praktisch das für einen Entwickler ist, so überflüssig sind Leerzeichen und Kommentare aber für den Browser. Es ist also sinnvoll, die ganzen überflüssigen Zeichen herauszufiltern.

Auch dies geschieht über Plugins wie z.B. Autoptimize. Die Warnung in Bezug auf JavaScript-Dateien gilt hier genauso wie bei der Überschrift „Zusammenfassen von CSS- und JS-Dateien“, und auch hier sind CSS- und HTML-Kompression eher gefahrenlos und daher auch von Anfängern realisierbar.

Plugin-Empfehlungen: Autoptimize.

Nicht angepasste Bildgrößen

Dies ist kein Caching, wird aber in vielen Caching-Plugins mit angeboten.

Bei schlecht programmierten Themes und Plugins kommt es häufig vor, dass auf Seiten völlig falsche Bildgrößen eingesetzt werden. Besonders häufig geschieht dies bei Multi-Purpose-Themes, welche Drag’n’Drop-Editoren wie Visual Composer mitbringen (was übrigens vielfach nicht am Visual Composer liegt, sondern an den Theme-Autoren, die den Visual-Composer in ihr Theme einbauen).

Diese zu großen Bildgrößen werden u.a. von Google PageSpeed bemängelt und sorgt letztlich durch die zu hohe Größe für viele überflüssige Daten, die übertragen werden müssen. Die Fehlerbehebung hier ist allerdings recht komplex, da dies abhängig vom eingesetzten Theme ist und man oft tief in den PHP-Code eintauchen muss, um derartige Fehler zu beheben. Aus diesem Grund wird dies hier nicht weiter behandelt. Es ist nicht desto trotz ein wichtiges Thema, da im Extremfall viele Megabyte eingespart werden können, so dass man bei der Theme-Auswahl auch aus diesem Grund auf eine saubere Programmierung achten sollte.

Plugin-Empfehlungen: Keine, das muss im Child-Theme mit WordPress Funktionen korrigiert werden.

Content Delivery Networks (CDNs)

Dies ist kein Caching, wird aber in vielen Caching-Plugins mit angeboten.

Zu CDNs habe ich mich an anderer Stelle schon mal ausführlich ausgelassen. Kurzzusammenfassung: in den meisten Fällen bringen sie wenig bis nichts, und manchmal machen sie Websites sogar langsamer.

Weitere Geschwindigkeitsoptimierungen

Es gibt eine Reihe an Optimierungen, die nicht über Caching-Systeme abgedeckt werden können. Ein gutes Beispiel hierfür sind gute Volltextsuchen: für diese braucht man schlicht eine Suchserver-Integration, was nicht „mal eben“ machbar ist. Caching-Techniken über derartige Plugins bringen also viel, aber sind nicht die Lösung für alles.

Fazit: Wie mache ich meine Seite nun schneller?

Wenn man eine Seite schneller machen möchte, dann sollte man nicht auf die Punktzahlen achten, sondern schauen, welche konkreten technischen Tips gegeben werden. Es muss nicht immer das ganz große Monster-Caching-Plugin sein, manche Dinge sind auch rein über die htaccess realisierbar. Ich hoffe, diese kleine Übersicht über die verschiedenen Caching-Mechanismen bringen in die Detail-Arbeit beim Beschleunigen von Websites ein wenig Licht hinein.

5 Kommentare zu “Caching: Was ist was?

  1. Nachdem im Artikel ja auch nicht nur 100% Caching Themen behandelt werden, sei die Frage erlaubt, ob und wie Server die http2 ausliefern können, sich in der Geschwindigkeit bemerkbar machen. M.E. messen die gängigen Tools das noch gar nicht.

    Gruß

    Hansjörg Leichsenring

    1. HTTP2 hat nun mal exakt gar nichts mit Caching zu tun und kann auch nicht ohne weiteres vom Webspace-Nutzer geändert werden. Daher kommt das hier nicht vor. Vielleicht folgt ja noch mal ein Artikel über serverseitige Einrichtung.

      1. Mir ginge es weniger um die Einrichtung als vielmehr um die Frage, wie ich mit den gängigen Tools prüfen kann, ob damit ein Ladezeitengewinn erreicht werden kann.

        Das es nicht mit Caching zu tun hat, ist mir schon klar, aber der Beitrag ging ja in Teilen auch darüber hinaus 😉

        1. Der Fokus des Artikels ist alles, was über Caching-Plugins realisierbar ist. HTTP2 ist das nun mal nicht.
          Wie du das testen kannst? Chrome / Firefox Developer Tools. HTTP2 anknipsen, ein paar Waterfall-Tests machen, Durchschnitt berechnen, HTTP2 ausknipsen, do the same again, Aussagen treffen. 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.