Wenn es um Performance-Debugging geht, gibt es eine Menge verfügbarer Werkzeuge. In den letzten Jahren habe ich nach einem gesucht, das wirklich leicht verwendbar ist und Engpässe selbst gut erkennt.

Es gibt einige, die spezifisch für WordPress sind, beispielsweise als Plugins, und einige für generelles Performance-Debugging in PHP. Andere wiederum benötigen eine bestimmte PHP-Erweiterung. Im folgenden Artikel decke ich alle möglichen Typen ab.

Das Ziel

Mein Ziel war das Identifizieren von Code-Teilen, die ich schneller machen kann. Die hauptsächliche Methode wäre, eine Anfrage anzuschauen und Funktionsaufrufe anzusehen, die sichtbar länger benötigen als der Rest, entweder weil sie lang benötigen, oder viel öfter laufen als gedacht.

Ein zweites Ziel war es, etwas zu finden, das auch in einer Produktivumgebung mit so wenig Overhead wie möglich verwendet werden, aber dennoch Performance-Metriken aus der echten Welt sammeln kann – und nicht nur in einer (lokalen) Testumgebung.

Disclaimer: Auch wenn die präsentierten Lösungen nicht meine Ziele abdecken, heißt das nicht, dass sie insgesamt schlecht sind.

Query Monitor

Das erste, das ich ausprobierte, war das Plugin Query Monitor. Es beinhaltet bereits einige Basis-Metriken und erlaubt eine gute Einsicht in die aktuelle Abfrage mit spezifischen Daten rund um WordPress. Es kann langsame oder doppelte SQL-Abfragen sehr gut erkennen und sie zum jeweiligen Code zuordnen. Ebenfalls kann es verwendet werden, um ein Profil von Teilen deines Codes manuell zu erstellen, nachdem es geladen wurde. Daher ist es leider nicht möglich, es sehr früh auszuführen oder innerhalb von vielen Funktionen des WordPress Cores, sodass es hier nicht zuverlässig funktioniert.

Für meine Ziele konnte ich es damit leider nicht zum laufen bringen (und insbesondere nicht automatisiert, da ich für jede Funktion manuell ein Profil erstellen müsste).

Code Profiler

Code Profiler ist ein weiteres Plugin, das explizit als „Performance Profiling and Debugging Made Easy“ vermarktet wird. Daher hatte ich große Hoffnung. In der kostenlosen Version kann es keine einzelnen Methoden und Funktionen nachverfolgen. Das geht aber in der Pro-Version für 89 $ pro Jahr oder 399 $ einmalig.

Technisch gesehen erfüllt die Pro-Version meine Anforderungen aus den Zielen, aber ich hatte drei Probleme damit:

  1. In meinem lokalen Test waren die Zahlen sehr fluktuierend. Es war immer ein anderes Plugin, das länger benötigte als gedacht. Das Deaktivieren dieses Plugins hatte beim nachfolgenden Test dann kaum eine Auswirkung.
  2. Der Trigger muss manuell ausgeführt werden, wodurch Daten aus dem Produktivsystem von anderen Benutzern praktisch unmöglich zu bekommen waren, wie ich es gerne hätte.
  3. Es basiert auf sogenannten „Ticks“, die in jede Datei eingefügt werden, bevor sie ausgeführt werden. Das ändert nicht nur die eigentlichen Dateien dynamisch, was Zeit und Ressourcen benötigt, sondern auch eigentlich nur für Debugging gedacht ist – nicht geeignet für ein Produktivsystem.

Xdebug

Wie sein Name bereits verrät, ist Xdebug primär ein Debugging-Werkzeug – und sollte niemals in Produktivumgebungen eingesetzt werden. Und auch wenn es sich damit sofort selbst disqualifiziert, möchte ich es für seine Performance-Debuggingmöglichkeiten vorstellen. Es hat einen Performance-Profiler integriert, das eine Cachegrind-Datei für eine entsprechend manuell ausgelöste Anfrage generiert, die dann über Werkzeuge wie KCachegrind eingesehen werden kann.

Diese Daten sind allerdings nicht ganz einfach zu interpretieren und manchmal eher verwirrend. Es benötigt daher eine tiefere Auseinandersetzung damit, wie Cachegrind-Dateien Daten sammeln und was sie am Ende beinhaltet und anzeigt.

Um zu laufen, muss eine PHP-Erweiterung geladen werden und es benötigt viele Ressourcen.

QCacheGrind-Ausgabe einer Anfrage mit allen ausgeführten Funktionen in einer Seitenleiste links und den entsprechenden Informationen rechts
QCacheGrind erfordert ein tiefgreifendes Verständnis der Datenerfassungsmethoden

XHProf

XHProf arbeitet ähnlich wie Xdebug in dieser Hinsicht. Und weil es sicherlich technisch sehr anders ist, ist die Ausgabe ähnlich (verwirrend). Es wird ebenfalls als PHP-Erweiterung geladen und manuell ausgelöst. Daher am Ende praktisch dieselben Gründe, es nicht im Produktivsystem einzusetzen.

Zusammenfassung einer Anfrage mit Anfragezeiten, Aufrufen, CPU- und Speicherauslastung für jede Funktion in einer Tabelle
Die Interpretation der gesammelten Daten von XHProf obliegt dem Benutzer

Sentry performance tracing

Da wir bereits Sentry als Fehlerbenachrichtigungs-Werkzeug verwenden, war die Entscheidung offensichtlich, auch dessen Profiling-Möglichkeiten zu testen. Es gibt ein WordPress-Plugin für Sentry, das auch Profiling unterstützt. Doch leider ist das nicht sehr präzise. Integriert ist die Unterstützung für die Bereiche Datenbank, HTTP, Transients, Plugins und Themes als Ganzes, was heißt, dass die einzelnen Bereiche immer die Metriken aller Bestandteile anzeigen, also für alle Plugins oder das Theme als Ganzes.

Auf diese Art erhält man zwar eine ungefähre Übersicht, wie viel jeder dieser Bereiche bei einer Anfrage benötigt, allerdings keine detaillierte Ansicht über einzelne Code-Teile.

Nachverfolgung in Sentry einer Anfrage mit einer einzigen HTTP-Anfrage (855,83 ms), aufgeteilt in app.bootstrap (326,88 ms) mit plugins.setup (62,04 ms), theme.setup (8,16 ms) und einigen Cache-Anfragen sowie in wp.handle (528,89 ms) mit einigen Cache-Anfragen.
Nur sehr wenige Einblicke in den tatsächlich ausgeführten Code in Sentry

Tideways

Ebenfalls mit einer PHP-Erweiterung kommt Tideways, ein Bezahldienst, der für die Prüfung von Performance-Problemen gedacht ist. Seine Nachverfolgung sieht ähnlich aus wie die von Sentry, ist allerdings wesentlich detaillierter und erlaubt eine tiefere Überprüfung jedes Funktionsaufruf (wenn ausgelöst). Es kommt mit einer Chrome-Erweiterung, um individuelle Anfragen direkt auszulösen, ohne Probleme wie „wie bekomme ich meinen Testing-Parameter an diese spezifische Ajax-Anfrage?“.

Zeitachse einer Anfrage mit mehreren Balken, die die benötigte Zeit für einzelne Codeteile darstellen
Eine übersichtliche Übersicht einer Anfrage in Tideways

In der Zeitleiste kannst du über jedes Element mit der Maus fahren und erhältst detaillierte Information darüber, was zu der Zeit aktiv war. Die interessantesten sind hier die in Helltürkis, da diese den Funktionen von Plugins innerhalb von WordPress entsprechen.

Der größte Negativpunkt ist wohl, dass man für Tideways zahlen muss und es nicht selbst hosten kann (zumindest habe ich darüber keine Informationen gefunden). Allerdings ist es wesentlich detaillierter und besser verständlich in der Art und Weise, wie es seine Daten präsentiert. Du kannst es umsonst für 14 Tage testen, ohne Zahlungsdaten zu hinterlegen.

Ebenfalls ist das Team rund um Tideways sehr interessiert an Feedback und du kannst ihnen jederzeit schreiben, wenn dir etwas auffällt oder du bei etwas Probleme hast. Und ja, mir ist aufgefallen, dass WordPress in der Nachverfolgung falsch geschrieben wird (erinnert mich an Feedback, das ich noch geben wollte).

Fazit

Letztendlich werde ich mich für Tideways entscheiden, da es für mich einfach die beste Lösung ist. Es kann langsamen Code selbstständig erkennen und präsentiert ihn auf eine Weise, mit der man leicht arbeiten kann. Außerdem ist es ausdrücklich für den Einsatz in der Produktion konzipiert.

Ich hätte mir gewünscht, etwas Ähnliches als kostenloses Open-Source-Werkzeug zu finden, aber leider sind die vorhandenen Lösungen nicht so leicht zugänglich oder entsprechen nicht meinen Zielen.

Neuveröffentlichungen

Schreibe einen Kommentar

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

Um auf deiner eigenen Website zu antworten, gib die URL deiner Antwort ein, die einen Link zur Permalink-URL dieses Beitrags enthalten sollte. Deine Antwort wird dann (möglicherweise nach der Moderation) auf dieser Seite erscheinen. Möchtest du deine Antwort aktualisieren oder entfernen? Aktualisiere oder lösche deinen Beitrag und gib die URL deines Beitrags noch einmal ein. (Mehr über die Funktion von Webmentions erfahren)