Caching in TYPO3 - Teil 1

Benni Mack

TYPO3 ist für seinen leistungsfähigen und flexiblen Caching-Mechanismus bekannt. Das Verständnis der grundlegenden Konzepte ermöglicht es Dir, schnellere Websites zu erstellen, die die Kundenbindung fördern - Besucher gehen schnell woanders hin, wenn Du sie warten lässt.

Unsere TYPO3-Caching-Blogreihe ist ideal für Entwickler, die mit TYPO3 vertraut sind und die die Kernkonzepte vollständig verstehen und robuste und schnellere Websites mit TYPO3 erstellen möchten.

Cache Me if you Can – Einblicke in Frontend-Caches in TYPO3

Was ist ein Cache?

Caching ist eine Technik, bei der eine Berechnung oder Abfrage einmal ausgeführt und dann zur späteren Verwendung gespeichert wird. Dadurch können alle nachfolgenden Abfragen viel schneller ausgeführt werden.

Ein Problem bei diesem Ansatz ist, dass die gecachte Version veraltet sein kann, wenn sich Informationen, wie z.B. ein Datenbankeintrag, ändern. Aus diesem Grund müssen die zwischengespeicherten Daten in regelmäßigen Abständen oder bei jeder Änderung der Quellinformationen invalidiert werden.

Die zwischengespeicherten Daten müssen auch durch bestimmte Parameter identifiziert werden, damit sie bei Bedarf abgerufen werden können.

Caching im TYPO3-Frontend

TYPO3 verfügt seit über einem Jahrzehnt über robuste Caching-Mechanismen. Diese haben sich als zuverlässig und flexibel erwiesen. Zum Zeitpunkt des Verfassens dieses Artikels befassen wir uns speziell mit TYPO3 v10, obwohl alle Konzepte bereits in früheren Versionen von TYPO3 in ähnlicher Weise existierten. 

Es gibt eine Reihe verschiedener Caches innerhalb von TYPO3. In diesem Artikel konzentrieren wir uns auf den Cache-Mechanismus zur Erzeugung und Darstellung einer einzelnen Seite.

Wenn TYPO3 eine bestimmte Seite auf einer Website rendert, holt es die Ausgabe – typischerweise HTML – aus dem internen Caching-Framework von TYPO3. TYPO3 bietet granulare Cache-Konfigurationsoptionen. Standardmäßig wird eine mit TYPO3 gerenderte Webseite 24 Stunden lang im TYPO3-Cache gespeichert. Dieser Cache-Eintrag enthält Daten, die auf allen Inhalten und Plugins einer Seite basieren, berücksichtigt aber auch alle relevanten URL-Query-String-Parameter (dazu später mehr) sowie den aktuell angemeldeten Benutzer und seine Benutzergruppe. Das bedeutet, dass TYPO3 die Ausgabe pro Benutzergruppe zwischenspeichert, so dass z.B. ein Menüeintrag, der nur für angemeldete Benutzer zugänglich ist, weiterhin aus dem Cache abgerufen werden kann.

Nicht cachebare Blöcke

Bestimmte Teile einer Seite können eine bestimmte Information enthalten, wie z.B. eine persönliche Begrüßung, wie "Guten Abend Benni", die niemals zwischengespeichert werden sollte. Bei b13 nennen wir diese Teile einer Seite "uncacheable blocks". TYPO3 bezeichnet sie als "USER_INT"- oder "COA_INT"-Objekte. Der Caching-Mechanismus von TYPO3 fügt Platzhalter als HTML-Kommentare in die zwischengespeicherten Daten ein – genau wie bei den Ansätzen Edge-Side-Includes oder Server-Side-Includes – und ersetzt sie am Ende jeder einzelnen Anfrage durch vollständig dynamische Inhalte.

Wenn es auf einer Website keine nicht cachebaren Blöcke gibt und der Besucher nicht eingeloggt ist, ist die Seite "vollständig cachebar". Dann kann TYPO3 die gesamte HTML-Ausgabe mit einer einzigen Abfrage direkt aus dem Cache holen.

Gefährlicher Parameter "no_cache".

Es ist möglich, die Speicherung von Daten im TYPO3-Cache oder das Abrufen von Daten aus dem Cache mit dem berüchtigten "no_cache"-Parameter zu deaktivieren. Diese Option kann durch den Aufruf einer URL wie https://b13.com/about-us?no_cache=1 verwendet werden. Site-Administratoren können dies auch über TypoScript einstellen. In früheren Versionen konnte dieses Flag sogar auf der Ebene der einzelnen Seiten gesetzt werden. Wir halten diese Option jedoch für sehr gefährlich. Wenn no_cache=1 verwendet wird, versucht TYPO3 nicht, etwas im Cache zu speichern oder aus diesem abzurufen. Es berechnet sämtliche Daten für jede einzelne Anfrage, was den Webserver anfällig für Denial-of-Service (DoS)-Angriffe macht, da jede Anfrage mehr CPU-Zeit benötigt als nötig wäre.

Um dem entgegenzuwirken, kann der no_cache-Parameter systemweit im Bereich "Admin Tools" => Einstellungen" deaktiviert werden, indem das Flag "disableNoCacheParameter" in der Liste "Configure Installation-Wide Options" aktiviert wird.

It is possible to disable storing anything in, or retrieving anything from, the TYPO3 cache by using the infamous “no_cache” parameter. This option can be used by calling a URL like https://b13.com/about-us?no_cache=1. Site administrators can also set this via TypoScript. In previous versions, this flag could even be set on a per-page level . However, we consider this option highly dangerous. When using no_cache=1, TYPO3 does not attempt to store or retrieve anything from the cache. It renders everything for every individual request, making the web server vulnerable to denial-of-service (DoS) attacks, as each request takes more CPU time than necessary to render.

To address this, the no_cache parameter can be disabled system-wide in the “Admin Tools” => Settings” area by activating the flag “disableNoCacheParameter” within the “Configure Installation-Wide Options” list.

Betrachtung des Caches beim Besuch einer Seite

Wenn wir zur Analyse und Verbesserung der Leistung von TYPO3 für eine Website konsultiert werden, betrachten wir die Website aus drei Blickwinkeln:

1. Beim ersten Besuch einer Seite ("Cache-Miss") – "First Hit".

In diesem Szenario werden alle Anweisungen von TYPO3 abgerufen, alle Inhalte und alle Menüs generiert, Links zu anderen Seiten aufgelöst, Berechtigungsprüfungen durchgeführt und alle referenzierten Bilder validiert und in der Größe angepasst. Sobald die endgültige Ausgabe berechnet ist, haben wir einen großen String.

Das Ergebnis wird im Cache "pages" gespeichert. Wenn es nicht cachebare Blöcke gibt, wird diese Information ebenfalls im Cache gespeichert, da diese Teile später bei jeder Anfrage ausgeführt werden müssen.

Die endgültige Ausgabe (HTML, JSON oder RSS) wird dann an den Browser gesendet.

Hinweis:

Es gibt verschiedene andere Caches (wie den "Core-Cache" und den "Labels-Cache"), die wir in einem späteren Kapitel näher betrachten werden. Auch diese können die Rendering-Dauer eines "First Hit" beeinflussen, wenn sie nicht richtig aufgewärmt wurden.

2. Besuch einer Seite mit einem gültigen Cache-Eintrag – "Cached Hit".

Der Inhalt einer Seite – Menüpunkte, Text, Medien usw. – wurden alle bei einem früheren Treffer auf die Seite berechnet und werden direkt aus dem Cache geholt. Das Aufrufen einer zwischengespeicherten Seite ist normalerweise etwa 10 Mal schneller als der erste Treffer. Du wirst also einen großen Ladeunterschied zwischen einem ersten Treffer und einem zwischengespeicherten Treffer feststellen.

2a) Keine nicht zwischengespeicherten Objekte und keine Benutzergruppen - "Fully Cached Page".

Wenn es keine uncachebaren Blöcke gibt und kein Benutzer angemeldet ist, könnte die Seite sogar von einem Proxy oder CDN gecached werden, was zu einer Ladezeit von ca. 20-40ms führt. Durch die Aktivierung der TypoScript-Option „config.sendCacheHeaders“ veranlasst man TYPO3, die entsprechenden HTTP-Header an den Browser zu senden, um die Seite für eine bestimmte Zeit innerhalb des Browser-Caches zu speichern.

2b) Eine Seite mit nicht cachebaren Objekten

Viele Plugins verwenden den uncacheable block mechanism (USER_INT). Anmeldeformulare oder Bereiche, die anzeigen, ob ein Benutzer angemeldet ist, sind häufige Anwendungsfälle. 

Einige Autoren von Erweiterungen überprüfen jedoch manchmal nicht vollständig, ob ein Plugin im Cache gespeichert werden kann. Selbst wenn das Plugin "fast in Echtzeit" Informationen anzeigt, könnte das Plugin so konfiguriert werden, dass es nur 1 Stunde, 30 Minuten oder sogar nur 1 Minute zwischengespeichert wird.

Hinweis:

Wenn ein Redakteur oder Administrator im TYPO3-Backend angemeldet ist, wird ein Cookie namens "be_typo_user" gesetzt, das den Redakteuren die Vorschau versteckter Seiten ermöglicht. Wenn Du im TYPO3-Backend angemeldet bist, wird eine Seite niemals aus dem Cache geholt oder in den Cache gelegt, daher solltest Du die Renderingzeit immer in einem separaten Browser oder einem privaten Browser-Tab messen, wenn Du nicht im Backend angemeldet bist.

Andererseits sollte ein Element wie das Anmeldeformular, das z.B. den aktuellen Anmeldestatus im Kopfbereich jeder Seite einer Website anzeigt, niemals im Cache gespeichert werden. Hier ist ein guter Tipp: Wenn Du diesen Teil mit einem AJAX-Aufruf holst, wird der Rest der Seite vollständig im Cache gespeichert. Tatsächlich macht der Community-Hub von TYPO3 – TYPO3.org – genau das. Das bedeutet aber auch, dass jeder Besuch einer Seite zwei Aufrufe der TYPO3-Anwendung anstößt.

Diese Informationen im Hinterkopf zu behalten und Vergleiche im Netzwerk-Tab eines Browsers durchzuführen, gibt dir bereits einen guten Hinweis darauf, wo sich ein möglicher Engpass einer TYPO3-Webseite verstecken könnte.

Jedes TYPO3-Projekt ist anders – und hat andere Anforderungen

TYPO3 wird mit vernünftigen Standard-Cache-Einstellungen für normale Websites ausgeliefert, so dass viele Benutzer beim Erstellen einer Website nichts konfigurieren müssen. Sie sind jedoch nicht für jeden möglichen Anwendungsfall optimiert, der von rein statischen bis hin zu hochdynamischen Websites reichen kann. Abhängig von einem der oben diskutierten Gesichtspunkte (siehe Abschnitte 1, 2, 2a und 2b) sendet TYPO3 die für Browser und Cache-Server relevanten HTTP-Response-Header bereits automatisch mit der zuvor beschriebenen TypoScript-Einstellung. Diese Header können jedoch durch Erweiterungen modifiziert werden, und die Site-Administratoren können sie ebenfalls konfigurieren. Um die Leistungsfähigkeit des Systems vollständig zu verstehen, muss man also sorgfältig analysieren, wie und warum diese Parameter gesendet werden.

Sobald ein Redakteur den Inhalt einer Seite verändert oder den Seitentitel bearbeitet, müssen die Seite und alle Seiten, die auf diese Seite zeigen, ihre Cache-Einträge ungültig machen. TYPO3 erledigt dies automatisch für dich unter der Haube.

Der zwischengespeicherte Treffer muss so schnell wie möglich erfolgen. Je nach Projekt sollte es nicht länger als 100-200ms dauern.

Die Analyse des ersten Treffers (am besten mit Hilfe von Profiling Tools wie Blackfire) kann die Wahrscheinlichkeit erhöhen, einen möglichen Engpass zu erkennen, wodurch sich einige Erkenntnisse darüber ergeben, wofür viel Rechenzeit benötigt wird. Sogenannte Mega-Menüs oder separate mobile Menüs auf derselben Seite für verschiedene Browser-Breakpoints erzeugen eine ungewöhnlich große Anzahl von Links (und HTML-Code) auf einer Seite, wodurch der nicht gecachte First Hit sehr langsam wird. 

Redakteure sollten niemals einen Cache manuell löschen müssen, wenn der Entwickler die volle Cache-Power in TYPO3 ausgeschöpft hat.

Im Folgenden zeigen wir Dir einige Tricks, die wir bei all unseren Projekten anwenden.

Optimieren der TYPO3-Caches

Wähle das passende Cache-Backend

Normalerweise speichert TYPO3 zwischengespeicherte Informationen in der Datenbank (in Tabellen wie "cache_pages" oder "cache_rootline"). Aber die Verwendung der Datenbank als Cache kann zu einer langsamen Seitendarstellung führen. Oftmals wird die Datenbank auf einem anderen Server gespeichert, was zu einer erhöhten Netzwerklatenz führt, die die Gesamtantwortzeit des Systems verlängert. Wenn der Datenbankdienst auf demselben Server läuft, kann die Datenbank viele CPU-Ressourcen verbrauchen. Eine relationale Datenbank wie MySQL ist nicht das ideale Werkzeug für das Caching, aber alle Hoster bieten eine für TYPO3 geeignete Datenbank an, so dass diese Option immer verfügbar ist.

In fortgeschritteneren Konfigurationen kann TYPO3 so angepasst werden, dass ein anderes Cache-Backend verwendet wird. Wir werden die verschiedenen Cache-Backends in einem weiteren Kapitel hervorheben.

Ein Cache-Backend ist wie ein Adapter, der dem System mitteilt, wo die zwischengespeicherten Informationen gespeichert werden sollen. TYPO3 bietet Adapter für Datenbanken, Dateisysteme, reine Arbeitsspeicher und verteilte Backends out-of-the-box. Als Faustregel gilt, dass die dringendsten Caches für die Frontend-Ausgabe in einen speicherbasierten Cache wie Redis oder Memcached gelegt werden, wodurch unsere Websites um 30% schneller geladen werden. Dazu gehören "pages" für die Ausgabe von Seiten im Cache, "pagesection" für TypoScript-Anweisungen und "rootline" für hierarchische Informationen von Seiten (allesamt die "Frontend-Caches", die ein Redakteur im TYPO3-Backend löschen kann). Aufgrund der Geschwindigkeitsverbesserung liefern wir alle unsere TYPO3-Projekte, die in unserer TYPO3-unterstützten Umgebung gehostet werden, standardmäßig mit einem konfigurierten Redis-Dienst aus. Eine vollständig zwischengespeicherte Seite in TYPO3, die mit Redis als Cache-Backend konfiguriert ist, benötigt nur eine Datenbankanfrage. Die Datenbank kann dann ausschließlich (und damit effizienter) für das Content-Management und die Datenabfrage genutzt werden.

Die Verwendung des richtigen Cache-Backends ist entscheidend, aber auch stark von der verwendeten Hosting-Infrastruktur abhängig. Wenn sich der Datenbankserver auf einem entfernten Server befindet, aber kein Speicher-Cache verfügbar ist, kann es möglich sein, die Caches auf dem Dateisystem zu speichern - wenn der Server mit einer schnellen SSD-Festplatte läuft. Aber: Von der Verwendung eines dateibasierten Cache-Backends wird bei verteilten Systemen, die Dateien über NFS austauschen, dringend abgeraten. Es gibt also im Allgemeinen nicht den besten Weg für alle da draußen – aber es gibt einen speziellen besten Weg für dein Projekt!

Bevor Du den Einsatz von TYPO3 in einem Multi-Knoten-Server-Setup aus Performance-Gründen in Betracht ziehst, stelle sicher, dass Du die tatsächlichen Engpässe Deines Systems verstehst und den zugrunde liegenden Code oder die Konfiguration optimierst.

Wir empfehlen dringend, sich an den Hoster zu wenden und nach Redis- oder Memcache-Unterstützung für die TYPO3-Website zu fragen.

Überprüfe deine Frontend-Ausgabe und passe die Cache-Lebensdauer an.

Wenn es sich um eine kleine TYPO3-Website handelt und sich die typischen Inhalte nicht täglich ändern, kann der Site-Administrator die TypoScript-Option config.cache_period auf 30 Tage oder mehr setzen. Damit wird der längste Zeitraum festgelegt, der vergehen kann, bevor der Browser den Server auf eine neue Version des Inhalts überprüft. Wenn eine bestimmte Seite, wie z.B. deine News-Seite, eine geringere Cache-Lebensdauer benötigt, kannst du dies in den Seiteneinstellungen ändern. Und nicht vergessen: Wenn man Inhalte einer Seite ändert, werden die Caches für diese Seite automatisch ungültig.

Und nicht vergessen:

Wenn Du den Seiteninhalt änderst, werden deine Caches für diese Seite automatisch ungültig gemacht.

Sicherstellen, dass das Caching nicht versehentlich abgeschaltet wird

Suche nach "no_cache"-Flags in deiner TypoScript-Konfiguration und versuche herauszufinden, warum diese Option überhaupt gesetzt wurde. Wir kennen langsame TYPO3-Setups, bei denen die Entwickler diese Option zu Entwicklungszwecken eingeschaltet haben, aber vergessen haben, diese Einstellung zu entfernen, bevor die Seite in Produktion ging.

Ist dieses Objekt wirklich nicht cachebar?

Das Admin-Panel von TYPO3 (wird mit der System-Erweiterung adminpanel geliefert) kann verwendet werden, um nicht cachebare Objekte auf der Webseite zu identifizieren und zu überprüfen, ob diese wirklich nicht gecachet werden sollten.

First Hits mit der Crawler-Erweiterung auslösen

Wenn der "First Hit" langsam ist und du weißt, dass du nichts dagegen tun kannst – vielleicht aufgrund verschiedener Benutzergruppen-Kombinationen und einem Loginstatus – gibt es Möglichkeiten, diese Seiten regelmäßig aufzuwärmen, indem du die Crawler-Erweiterung oder eine benutzerdefinierte Aufwärm-Erweiterung verwendest.

Verwendung eines Reverse-Proxy oder CDN

Der Webserver und die verwendete PHP-Version könnten auch zu Engpässen werden, wenn man eine leistungsfähigere Website in Betracht zieht, bei der mehr Optimierungen in angemessener Zeit erreicht werden könnten. Ein Audit über web.dev kann feststellen, ob es andere Teile als TYPO3 gibt, die das Laden Ihrer Website beschleunigen könnten.

Wir verwenden web.dev und Blackfire, um die Performance-Renderingzeiten unseres Setups zu optimieren, um sicherzustellen, dass wir das Beste aus TYPO3 herausholen. Wende dich gerne an uns und konsultiere b13, um die Zufriedenheit deiner Website-Besucher zu erhöhen.

Wenn du deine PHP-Ausführungszeiten optimiert hast und die Renderingzeiten einer vollständig gecachten Seite noch verbessern möchtest, solltest du einen Proxy wie Varnish oder ein CDN verwenden. Dies erfordert etwas Erfahrung von Seiten der Entwickler, aber wir glauben, dass diese Optimierungen den Aufwand wert sind. Bei b13 verwenden wir Cloudflare als CDN-Anbieter. Cloudflare bietet einen globalen Einsatzbereich für die Bereitstellung von vollständig zwischengespeicherten Inhalten und noch mehr Funktionen wie eine Web Application Firewall, so dass die Server-Setups noch weniger CPU-Leistung benötigen, da die meisten Anfragen bereits über das CDN abgewickelt werden. Aber Vorsicht: Mit mehr Caching kommen mehr Fallstricke, wenn Cache-Einträge nicht richtig invalidiert werden.

Vorteile einer cachefähigen Webseite

Unser Kerngeschäft bei b13 ist die Entwicklung hochgradig anpassbarer, mehrsprachiger Websites mit globaler Reichweite. Leistungsfähige Websites sind ein Muss für die heutigen global agierenden Unternehmen. Das Gespräch mit SEO-Agenturen und Suchmaschinenbetreuern zeigt uns, dass Performance nicht nur für das Suchranking der entscheidende Vorteil ist, sondern auch dafür, dass sich die Nutzer auf der Website wohlfühlen.

TYPO3 unterstützt uns dabei, genau das zu erreichen, wenn wir uns an die Best Practices für das interne Caching halten.

Was also kannst du tun?

  • Stelle sicher, dass deine Website gemäß den oben genannten Schritten vollständig optimiert wurde. Wenn du trotzdem das Gefühl hast, dass deine bestehende TYPO3-Website verbesserungswürdig ist, frag uns nach einem unabhängigen Audit deines Projekts.
  • Stelle sicher, dass die Einrichtung des Webservers nicht der eigentliche Engpass ist, und optimiere die Leistung über PHP hinaus.

Unsere nächsten Blog-Posts in unserer Caching-Serie werden dir weitere Einblicke in den berüchtigten "cHash"-Parameter geben, und später werden wir dir auch zeigen, wie deine Redakteure nie wieder einen Cache löschen müssen, weil du alles perfekt optimiert hast!