Es ist eine Situation, die jeder Internetnutzer kennt: man ist auf der Suche nach einer Information, tippt den entsprechenden Suchbegriff in einer Suchmaschine der Wahl ein, klickt auf das vielversprechendste Resultat und es passiert… nichts! Anstatt dass sich die Seite in kürzester Zeit aufbaut, legt der Browser einige “Gedenksekunden” ein und die Seite will die begehrte Information einfach nicht preisgeben. Diese Situation ist für die Nutzer frustrierend und sie neigen dazu, ein anderes Suchergebnis anzuklicken, das “schneller” reagiert – somit haben Joomla-Webmaster ein großes Interesse daran, eine möglichst schnelle Seite zu betreiben. Wie aber lassen sich Performance-Probleme in Joomla überhaupt systematisch analysieren, um anschließend an den richtigen Stellen Änderungen zu machen?
Zuallererst ist es wichtig zu verstehen, dass sich der Prozess des Seitenaufrufs in zwei Teile aufsplittet:
Nach dem Aufruf der Seite startet zuerst die serverseitige Generierung der Website. Das bedeutet, dass der Webserver den Aufruf an das jeweilige CMS übergibt, das CMS dann alle benötigten PHP-Skripte lädt, die Datenbankverbindung herstellt, verschiedenste Abfragen in der Datenbank macht und so Stück für Stück den HTML-Code der fertigen Seite zusammenstellt.
Während dieser Phase der Generierung findet keine Kommunikation mit dem Web-Browser statt, es ist noch kein einziges Byte an den Browser ausgegeben worden, der somit auch noch nichts darstellen kann – diese Phase ist für Nutzer somit besonders frustrierend: es gibt keinen Fortschritt, es ist nicht abzusehen wann es weiter geht und es ist unklar, warum es überhaupt so lange dauert.
Wenn die Generierung des HTML schließlich abgeschlossen ist, übergibt das CMS den fertigen Code an den Webserver und dieser liefert das Resultat an den Browser. Dieser Zeitpunkt, bei dem das erste Mal Daten an den Server fließen und somit ein “erstes Byte” den Webserver erreicht, wird im Fachjargon als “Time to first Byte”, kurz TTFB bezeichnet.
Nachdem der HTML-Code beim Browser angekommen ist, folgt der zweite Teil des Seitenaufruf-Prozess: der Browser arbeitet das HTML-Dokument systematisch von oben nach unten ab, ruft Assets wie JavaScript- oder CSS-Dateien ab, lädt Bilder herunter oder bindet externe Schriftarten ein. Dieser Prozess ist für Nutzer oftmals wesentlich weniger zermürbend als das Warten bei langen TTFB-Zeiten, da es einen sichtbaren Fortschritt beim Seitenaufbau gibt und eventuell sogar schon erste Texte sichtbar sind, die man nach der gesuchten Information “scannen” kann.
Tools für die Optimierung des browserseitigen Renderings
Die Optimierung des browserseitigen Renderings ist für alle CMS sehr ähnlich. Hier gibt es eine bunte Vielzahl von Tests und Tools, die aufzeigen können, wo das Problem liegt. Neben dem Platzhirsch PageSpeed Insights von Google möchte ich hierbei insbesondere noch auf WebPagetest.org und GTmetrix.com verweisen, denn diese Tools geben wesentliche detailliertere Einblicke in den Prozess des Seitenaufbaus.
Spannender ist somit die Optimierung der TTFB! Externe Tools helfen hier prinzipbedingt nicht weiter, denn die gesamte Generierung findet ja serverseitig statt und erlaubt keine Einblicke in die genauen Abläufe. Wie lassen sich also langsame Seitengenerierungszeiten in Joomla analysieren und beheben? Mit dem Joomla-Debugging Modus!
Der Joomla-Debugging Modus – ein Blick unter die Haube
Der Joomla-eigene Debugging Modus bringt vielfältige Einblicke in der Generierungsprozess der Seite. Neben allgemeinen Debugging-Funktionen wie z.B. der Ausgabe von etwaigen Log-Nachrichten oder der Prüfung der Syntax von Sprachdateien bringt das integrierte Joomla-Debugging Plugin insbesondere 2 Funktionen mit, die für die Performanceoptimierung extrem wichtig sind:
- Eine generelle “Profiling” Funktion, aus der hervorgeht, welcher Teil der Seitengenerierung wieviel Zeit in Anspruch nimmt
- Eine Logging-Funktion für Datenbankabfragen, mit der sich besonders langsame oder doppelte Abfragen identifizieren lassen
Der erste Schritte ist somit die Aktivierung des entsprechenden Plugins und des systemweiten Debug-Modus – bevor es hier los geht, bitte ich noch darum den folgenden Hinweis zu lesen und zu verinnerlichen:
ACHTUNG: Der Joomla-Debugging Modus gibt sicherheitsrelevante Informationen aus und sollte daher nicht auf öffentlich erreichbaren Seiten aktiviert werden. Nutzen Sie den Debug-Mode daher nur auf geschützten Test-Seiten!
Den Debug-Modus aktivieren
Um den Modus zu aktivieren, muss als erstes das zugehörige Plugin aktiviert sein. Dieses finden Sie im Plugin-Manager des Backends unter “Erweiterungen” > “Plugins”. Der Name des Plugins lautet “System – Debug” und kann z.B. über die Filterfunktion leicht gefunden werden. Das Plugin hat diverse Optionen, um zum Beispiel das Logging der Datenbankabfragen zu unterdrücken oder die Ausgabe von Log-Nachrichten anzupassen, in der Regel sollten die Standardeinstellungen jedoch ausreichend sein.
Im zweiten Schritt gilt es dann, den systemweiten Joomla-Debugging Modus zu aktivieren. Die entsprechende Option finden Sie in der Joomla-Konfiguration unter “System” > “Konfiguration” im Reiter “System”. Die Option “System debuggen” sollte hierfür auf “Ja” gestellt werden.
Ruft man nun die Seite im Frontend auf, wird ans Ende der Seite die Debug-Ausgabe angehängt, die sich in verschiedene Abschnitte aufteilt:
- Sitzung: Enthält die Daten der jeweiligen User-Session – für die Performance in der Regel wenig spannend
- Profil zum Laufzeitverhalten: Hier wird es spannend! In diesem Bereich findet man den Zeit- und Speicherverbrauch der einzelnen Arbeitsschritte
- Speichernutzung: Gibt den gesamten durch Joomla verbrauchten Arbeitsspeicher aus
- Datenbankabfragen: Hier werden die individuellen Datenbankabfragen ausgegeben
- Protokollnachrichten: Enthält etwaige Log-Messages
Die Profiling-Informationen interpretieren
Im ersten Schritt zeige ich Ihnen nun, wie Sie die Informationen im Bereich “Profil zum Laufzeitverhalten” deuten können. Im oberen Bereich finden Sie hier zwei verschiedenfarbige Balken mit den Überschriften “Zeit” und “Speicher”. Diese Balken sind gewissermaßen ein Zeitstrahl und stellen den Zeit- bzw. Speicherverbrauch jedes Generierungsschritts grafisch dar. Der Balken beginnt links mit dem allerersten Schritt (in der Regel “afterLoad”) und bildet dann nach rechts hin die weiteren Schritte in der tatsächlich aufgetretenen Reihenfolge ab. Benötigt ein Schritt nur wenig Zeit bzw. Speicher, wird er hierbei im Balken als grünes Segment dargestellt. Bewegt sich der Verbrauch im mittleren Bereich ist das Segment gelb und Bereiche mit hohem Verbrauch sind rot. Beim Mouseover über den jeweiligen Bereich erscheint der Name des zugehörigen Schritts, sodass ein Hover über die roten Balkensegemente schnell die kritischen Parts der Seitengenerierung zeigen.
Was bedeuten nun aber die einzelnen Schritte? Welcher Seitenteil wird da jeweils erzeugt? Hier hilft die folgende Tabelle:
Schritt | Bedeutung | Rolle beim Debugging |
---|---|---|
afterLoad | Skript gestartet | |
afterInitialise | Die Dateien des Joomla-Frameworks wurden geladen, erste Plugins wurden aufgerufen | Hohe Werte bei diesem Schritt können ein Hinweis darauf sein, dass der Server stark ausgelastet ist und die für das Einlesen der Dateien benötigten Festplattenzugriffe nur langsam durchführen kann |
afterRoute | Joomla hat geprüft, welche URL übergeben wurde und welche Komponente für diesen Seitenaufruf zuständig ist | Seiten mit extrem vielen Menüeinträgen haben hier oft Probleme – eine Reduzierung der Einträge kann hier helfen |
beforeRenderComponent | Das Seitentemplate und die Sprachdateien werden geladen | Wird ein komplexes Template-Framework verwendet, treibt das oft die Ladezeit bei diesem Schritt in die Höhe |
before/after Access | Das Berechtigungssystem wird geladen und die Zugriffsrechte werden geprüft | Seiten mit extrem vielen Inhalten haben hier teils Probleme |
afterRenderComponent | Die Komponente der jeweiligen Seite wurde ausgeführt | Hier lässt sich die Performance der verwendeten Komponente prüfen – ist der Wert hier extrem Hoch, ist die Komponente der richtige Ansatzpunkt für Optimierungen |
afterDispatch | Plugins des “afterDispatch”-Events sind ausgeführt worden | Bei hohen Werten kann man Drittplugins systematisch deaktivieren, bis der Wert sinkt und darüber den Übeltäter eingrenzen |
afterRenderModule | Das im Schritt angegebene Modul wurde ausgeführt | Bremsen einzelne Module die Seitenausführung, lässt sich der Verursacher hier leicht finden |
afterRender | Die Seite wurde fertig generiert, Plugins für für das “afterRender”-Event wurden ausgeführt | Wenn dieser Schritt sehr langsam ist, sind oftmals Plugins die Ursache, die den HTML-Code der Gesamtseite modifizieren. Typische Kandidaten sind Ersetzung- oder Pagespeed-Optimierungsplugins. |
Mit diesen Informationen kann man nun sehr leicht eingrenzen, welcher Teil der Seitengenerierung besonders viel Zeit verbraucht und wo somit zuerst für die Optimierung angesetzt werden sollte. Optimierung kann dabei bedeuten, das z.B. das Caching in einem langsamen Modul aktiviert wird oder eine unperformante Komponente durch eine alternative Extension ersetzt wird. Statt zu raten kann man mit dem Joomla-Debugging Modus also gezielte Maßnahmen ergreifen.
Was aber, wenn Performance-Probleme z.B. eine Eigenentwicklung betreffen oder eine langsame Komponente nicht ersetzt werden kann? In dem Fall lohnt sich oftmals ein Blick in den sog. Query Profiler, in dem alle Datenbankabfragen aufgezeichnet werden. Falsch strukturierte Datenbankabfragen sind oft die technische Grundursache für schlechte Performance bei Dritterweiterungen und daher ein wichtiger Anhaltspunkt.
Datenbankabfragen analysieren mit dem Query Profiler
Die aufgezeichneten Abfragen finden sich im Bereich “Datenbankabfragen” des Debug-Bereichs. Dort findet sich für jede einzelne Datenbankabfrage eine Fülle von hilfreichen Informationen. Die wichtigsten Parameter sind hier:
- (1) Abfragezeit: Gibt an, wie lange die entsprechende Abfrage zur Ausführung gebraucht hat
- (2) Zeilen zurückgegeben: Wieviele Resultate hat die Datenbank an das PHP-Skript zurück gegeben? Wird eventuell eine Limitierung der Ergebnisse in PHP gemacht, anstatt dies perfomanter in der DB erledigen zu lassen?
- (3) Query: Die eigentliche Abfrage
- (4) Erklären: Gibt das Ergebnis des jeweiligen EXPLAIN-Aufrufs zurück – hier lässt sich gut ablesen, ob z.B. Indizes in den Tabellen fehlen
- (5) Aufrufstapel (Call Stack): Zeigt, woher die entsprechende Abfrage überhaupt kommt, also in welchem Teil von Joomla der Aufruf generiert wurde
Oberhalb der eigentlichen Abfrage findet sich die Bereits bekannte Balkendarstellung – besonders breite Segmente stellen hier Abfragen dar, die viel Zeit in Anspruch nehmen und daher mit Priorität geprüft werden sollten.
Fazit
Der Joomla-Debugging Modus ist mit seinen Profiling-Werkzeugen ein sehr wertvolles Hilfsmittel, um serverseitige Performance-Probleme zu konkreten Bereichen des Systems zuordnen und dann anschließend beheben zu können. Somit muss nicht geraten werden, ob vielleicht dieses oder jenes Modul den Seitenaufbau bremst, sondern es kann systematisch und auf Basis messbare Zahlen vorgegangen werden.
Insbesondere bei komplexeren Projekten ist diese analytische Vorgehensweise unumgänglich und erlaubt teils beeindruckende Verbesserungen mit extrem wenig Aufwand. So hat z.B. das simple Aufsplitten einer großen Datenbankabfrage in zwei kleinere Abfragen den Aufruf einer von mir optimierten Seite von über 8 Sekunden auf unter 400ms beschleunigt. Mit weniger als 1 Stunde Aufwand konnte die Performance somit um den Faktor 20 verbessert werden.
Schauen Sie also auch mal in Ihren Debug-Modus – vielleicht schlummert dort großes Potenzial für eine schnellere Seite.
Bildnachweis: Pixabay Free Pictures
- HTTP Security-Header – Wie Sie die schlummernden Wachhunde des Browsers wecken - 6. November 2018
- Wieso ist das so langsam? – Joomla-Debugging von Performance-Problemen - 15. Oktober 2018