Der erweiterte Leitfaden zur Optimierung der WordPress-Leistung
Veröffentlicht: 2022-03-11Heute betreibt WordPress über 30 % des Internets. Es ist einfach zu bedienen, unglaublich beliebt und wird in absehbarer Zeit nirgendwo hingehen.
Aber WordPress kann langsam sein. Wie optimiert man es also?
Es gibt jede Menge Artikel darüber, wie man WordPress einstellt und optimiert. Tatsächlich bietet WordPress selbst einen robusten Leitfaden zur WordPress-Optimierung.
Diese Artikel und Tutorials decken größtenteils ziemlich grundlegende, aber nützliche Konzepte ab, wie die Verwendung von Cache-Plug-ins, die Integration in Content Delivery Networks (CDNs) und die Minimierung von Anfragen. Obwohl diese Tipps sehr effektiv und sogar notwendig sind, lösen sie letztendlich nicht das zugrunde liegende Problem: Die meisten langsamen WordPress-Sites sind das Ergebnis von schlechtem oder ineffizientem Code.
Daher zielt dieser Artikel hauptsächlich darauf ab, Entwicklern und WordPress-Entwicklungsfirmen einige Richtlinien an die Hand zu geben, die ihnen helfen können, die zugrunde liegenden Ursachen vieler WordPress-Leistungsprobleme anzugehen.
WordPress bietet viele leistungsorientierte Funktionen, die von Entwicklern oft übersehen werden. Code, der diese Funktionen nicht nutzt, kann die einfachsten Aufgaben verlangsamen, z. B. das Abrufen von Beiträgen. Dieser Artikel beschreibt vier mögliche Lösungen, die einige der zugrunde liegenden Probleme hinter der langsamen WordPress-Leistung angehen.
Beiträge abrufen
WordPress bietet die Möglichkeit, jede Art von Post aus der Datenbank zu holen. Dazu gibt es drei grundlegende Möglichkeiten:
Verwenden der Funktion
query_posts()
: Dies ist ein sehr direkter Ansatz, aber das Problem ist, dass er die Hauptabfrage überschreibt, was zu Unannehmlichkeiten führen kann. Dies könnte beispielsweise ein Problem sein, wenn wir irgendwann nach dem Abrufen der Beiträge (z. B. insidefooter.php
) feststellen möchten, mit welcher Art von Seite wir es zu tun haben. Tatsächlich enthält die offizielle Dokumentation einen Hinweis, der von der Verwendung dieser Funktion abrät, da Sie eine zusätzliche Funktion aufrufen müssen, um die ursprüngliche Abfrage wiederherzustellen. Darüber hinaus wirkt sich das Ersetzen der Hauptabfrage negativ auf die Ladezeiten der Seiten aus.Verwenden der Funktion
get_posts()
: Dies funktioniert fast wiequery_posts()
, ändert jedoch nicht die Hauptabfrage. Auf der anderen Seite führtget_posts()
die Abfrage standardmäßig mit dem auftrue
gesetzten Parametersuppress_filters
aus. Dies könnte zu Inkonsistenzen führen, insbesondere wenn wir abfragebezogene Filter in unserem Code verwenden, da Beiträge, die Sie auf einer Seite nicht erwarten, von dieser Funktion zurückgegeben werden können.Verwendung der
WP_Query
-Klasse: Meiner Meinung nach ist dies der beste Weg, um Beiträge aus der Datenbank abzurufen. Sie ändert die Hauptabfrage nicht und wird wie jede andere WordPress-Abfrage auf ihre standardmäßige Weise ausgeführt.
Aber welche Methode wir auch verwenden, um mit der Datenbank zu interagieren, es gibt andere Dinge, die wir berücksichtigen müssen.
Einschränkung der Abfrage
Wir sollten immer angeben, wie viele Posts unsere Abfrage abrufen muss.
Um dies zu erreichen, verwenden wir den Parameter posts_per_page
.
WordPress lässt uns -1 als möglichen Wert für diesen Parameter angeben, in diesem Fall versucht das System, alle Beiträge abzurufen, die die definierten Bedingungen erfüllen.
Dies ist keine gute Vorgehensweise, auch wenn wir sicher sind, dass wir nur wenige Ergebnisse als Antwort zurückbekommen.
Zum einen können wir selten sicher sein, dass wir nur wenige Ergebnisse zurückbekommen. Und selbst wenn wir können, erfordert das Festlegen von No Limit, dass die Datenbank-Engine die gesamte Datenbank nach Übereinstimmungen durchsucht.
Umgekehrt ermöglicht das Einschränken der Ergebnisse der Datenbank-Engine oft, die Daten nur teilweise zu scannen, was sich in einer kürzeren Verarbeitungszeit und einer schnelleren Reaktion niederschlägt.
Eine andere Sache, die WordPress standardmäßig tut, was sich negativ auf die Leistung auswirken kann, ist, dass es versucht, Sticky Posts zu bringen und zu berechnen, wie viele Zeilen in der Abfrage gefunden wurden.
Oft benötigen wir diese Informationen jedoch nicht wirklich. Das Hinzufügen dieser beiden Parameter deaktiviert diese Funktionen und beschleunigt unsere Abfrage:
$query = new WP_Query( array( 'ignore_sticky_posts' => true, 'no_found_rows' => true ) );
Ausschließen von Beiträgen aus der Abfrage
Manchmal möchten wir bestimmte Beiträge von der Abfrage ausschließen. WordPress bietet einen ziemlich direkten Weg, dies zu erreichen: die Verwendung des Parameters post__not_in
. Zum Beispiel:
$posts_to_exclude = array( 1, 2, 3 ); $posts_per_page = 10; $query = new WP_Query( array( 'posts_per_page' => $posts_per_page, 'post__not_in' => $posts_to_exclude ) ); for ( $i = 0; $i < count( $query->posts ); $i++ ) { //do stuff with $query->posts[ $i ] }
Dies ist zwar ziemlich einfach, aber nicht optimal, da es intern eine Unterabfrage generiert. Besonders bei großen Installationen kann dies zu langsamen Reaktionen führen. Es ist schneller, diese Verarbeitung mit einigen einfachen Änderungen vom PHP-Interpreter erledigen zu lassen:
$posts_to_exclude = array( 1, 2, 3 ); $posts_per_page = 10; $query = new WP_Query( array( 'posts_per_page' => $posts_per_page + count( $posts_to_exclude ) ) ); for ( $i = 0; $i < count( $query->posts ) && $i < $posts_per_page; $i++ ) { if ( ! in_array( $query->posts[ $i ]->ID, $posts_to_exclude ) ) { //do stuff with $query->posts[ $i ] } }
Was habe ich dort gemacht?
Grundsätzlich habe ich der Datenbank-Engine etwas Arbeit abgenommen und sie stattdessen der PHP-Engine überlassen, die dasselbe tut, aber im Speicher, was viel schneller ist.
Wie?
Zuerst habe ich den Parameter post__not_in
aus der Abfrage entfernt.
Da uns die Abfrage möglicherweise einige Posts bringt, die wir als Ergebnis nicht wollen, habe ich den Parameter posts_per_page
erhöht. Auf diese Weise stelle ich sicher, dass ich, selbst wenn ich einige unerwünschte Posts in meiner Antwort gehabt hätte, dort mindestens $posts_per_page
gewünschte Posts hätte.
Wenn ich dann die Posts durchlaufe, verarbeite ich nur diejenigen, die sich nicht im Array $posts_to_exclude
.
Vermeidung komplexer Parametrierung
Alle diese Abfragemethoden bieten eine Vielzahl von Möglichkeiten zum Abrufen von Beiträgen: nach Kategorien, nach Metaschlüsseln oder -werten, nach Datum, nach Autor usw.
Und obwohl diese Flexibilität eine leistungsstarke Funktion ist, sollte sie mit Vorsicht verwendet werden, da diese Parametrisierung zu komplexen Tabellenverknüpfungen und teuren Datenbankoperationen führen könnte.
Im nächsten Abschnitt skizzieren wir einen eleganten Weg, um dennoch eine ähnliche Funktionalität zu erreichen, ohne die Leistung zu beeinträchtigen.
Das Beste aus den WordPress-Optionen herausholen
Die WordPress Options API bietet eine Reihe von Tools zum einfachen Laden oder Speichern von Daten. Es ist nützlich für den Umgang mit kleinen Informationen, für die andere von WordPress angebotene Mechanismen (wie Posts oder Taxonomien) zu komplex sind.

Wenn wir beispielsweise einen Authentifizierungsschlüssel oder die Hintergrundfarbe der Kopfzeile unserer Website speichern möchten, suchen wir nach Optionen.
WordPress gibt uns nicht nur die Funktionen, um damit umzugehen, sondern ermöglicht es uns auch, dies auf die effizienteste Weise zu tun.
Einige der Optionen werden sogar direkt beim Systemstart geladen und ermöglichen uns so einen schnelleren Zugriff (beim Erstellen einer neuen Option müssen wir überlegen, ob wir sie automatisch laden möchten oder nicht).
Stellen Sie sich zum Beispiel eine Website vor, auf der wir ein Karussell haben, das aktuelle Nachrichten anzeigt, die im Backend angegeben sind. Unser erster Instinkt wäre, dafür einen Metaschlüssel wie folgt zu verwenden:
// functions.php add_action( 'save_post', function ( $post_id ) { // For simplicity, we do not include all the required validation before saving // the meta key: checking nonces, checking post type and status, checking // it is not a revision or an autosaving, etc. update_post_meta( $post_id, 'is_breaking_news', ! empty ( $_POST['is_breaking_news'] ) ); } ); // front-page.php $query = new WP_Query( array( 'posts_per_page' => 1, 'meta_key' => 'is_breaking_news' ) ); $breaking_news = $query->posts[0] ?: NULL;
Wie Sie sehen können, ist dieser Ansatz sehr einfach, aber nicht optimal. Es führt eine Datenbankabfrage durch, um einen Beitrag mit einem bestimmten Metaschlüssel zu finden. Wir könnten eine Option verwenden, um ein ähnliches Ergebnis zu erzielen:
// functions.php add_action( 'save_post', function ( $post_id ) { // Same comment for post validation if ( ! empty ( $_POST['is_breaking_news'] ) ) update_option( 'breaking_news_id', $post_id ); } ); // front-page.php if ( $breaking_news_id = get_option( 'breaking_news_id' ) ) $breaking_news = get_post( $breaking_news_id ); else $breaking_news = NULL;
Die Funktionalität variiert leicht von einem Beispiel zum anderen.
Im ersten Codeabschnitt erhalten wir immer die neuesten Eilmeldungen in Bezug auf das Veröffentlichungsdatum des Beitrags.
In der zweiten wird jedes Mal, wenn ein neuer Beitrag als Eilmeldung festgelegt wird, die vorherige Eilmeldung überschrieben.
Aber da wir wahrscheinlich immer nur einen Breaking-News-Post auf einmal haben wollen, sollte das kein Problem sein.
Und am Ende haben wir eine schwere Datenbankabfrage (unter Verwendung von WP_Query
mit Metaschlüsseln) in eine einfache und direkte Abfrage (Aufruf get_post()
) geändert, was ein besserer und leistungsfähigerer Ansatz ist.
Wir könnten auch eine kleine Änderung vornehmen und Transienten anstelle von Optionen verwenden.
Transienten funktionieren ähnlich, ermöglichen es uns jedoch, eine Ablaufzeit anzugeben.
Zum Beispiel passt es für Eilmeldungen wie angegossen, weil wir einen alten Beitrag nicht als Eilmeldung haben wollen, und wenn wir die Aufgabe, diese Eilmeldung zu ändern oder zu löschen, dem Administrator überlassen, [s]er könnte es vergessen es. Mit zwei einfachen Änderungen fügen wir also ein Ablaufdatum hinzu:
// functions.php add_action( 'save_post', function ( $post_id ) { // Same comment for post validation // Let's say we want that breaking news for one hour // (3600 = # of seconds in an hour). if ( ! empty ( $_POST['is_breaking_news'] ) ) set_transient( 'breaking_news_id', $post_id, 3600 ); } ); // front-page.php if ( $breaking_news_id = get_transient( 'breaking_news_id' ) ) $breaking_news = get_post( $breaking_news_id ); else $breaking_news = NULL;
Persistentes Caching aktivieren
WordPress verfügt nativ über einen Objekt-Caching-Mechanismus.
Optionen werden beispielsweise mit diesem Mechanismus zwischengespeichert.
Aber standardmäßig ist dieses Caching nicht persistent, was bedeutet, dass es nur für die Dauer einer einzigen Anfrage existiert. Alle Daten werden für einen schnelleren Zugriff im Arbeitsspeicher zwischengespeichert, sind aber nur während dieser Anfrage verfügbar.
Die Unterstützung von persistentem Caching erfordert die Installation eines Plug-ins für persistenten Cache.
Einige Full-Page-Cache-Plugins enthalten ein persistentes Cache-Plugin (z. B. W3 Total Cache), andere jedoch nicht, und wir müssen es separat installieren.
Es hängt von der Architektur unserer Plattform ab, ob wir Dateien, Memcached oder einen anderen Mechanismus verwenden, um zwischengespeicherte Daten zu speichern, aber wir sollten diese erstaunliche Funktion nutzen.
Man könnte fragen: „Wenn das so ein tolles Feature ist, warum aktiviert WordPress es nicht standardmäßig“?
Der Hauptgrund ist, dass abhängig von der Architektur unserer Plattform einige Cache-Techniken funktionieren und andere nicht.
Wenn wir unsere Website beispielsweise auf unserem verteilten Server hosten, sollten wir ein externes Cache-System verwenden (z. B. einen Memcached-Server). Wenn sich unsere Website jedoch auf einem einzelnen Server befindet, könnten wir etwas Geld sparen, indem wir einfach das Dateisystem verwenden zu cachen.
Eine Sache, die wir berücksichtigen müssen, ist der Cache-Ablauf. Dies ist der häufigste Fallstrick bei der Arbeit mit persistentem Caching.
Wenn wir dieses Problem nicht richtig angehen, werden sich unsere Benutzer darüber beschweren, dass sie die von ihnen vorgenommenen Änderungen nicht sehen oder dass es zu lange gedauert hat, bis ihre Änderungen übernommen wurden.
Manchmal müssen wir Kompromisse zwischen Leistung und Dynamik eingehen, aber trotz dieser Hindernisse ist persistentes Caching etwas, das praktisch jede WordPress-Installation nutzen sollte.
AJAXing der schnellste Weg
Wenn wir über AJAX mit unserer Website kommunizieren müssen, bietet WordPress zum Zeitpunkt der Verarbeitung der Anfrage auf der Serverseite eine gewisse Abstraktion.
Obwohl diese Techniken beim Programmieren von Back-End-Tools oder Formularübermittlungen vom Front-End verwendet werden können, sollten sie vermieden werden, wenn dies nicht unbedingt erforderlich ist.
Der Grund dafür ist, dass wir zur Verwendung dieser Mechanismen verpflichtet sind, eine Post-Anfrage an eine Datei zu stellen, die sich im wp-admin
Ordner befindet. Die Mehrheit (wenn nicht alle) der WordPress-Ganzseiten-Caching-Plugins cachen weder Post-Requests noch Aufrufe von Administratordateien.
Wenn wir beispielsweise dynamisch mehr Posts laden, wenn der Benutzer auf unserer Homepage scrollt, wäre es besser, direkt eine andere Front-End-Seite aufzurufen, die die Vorteile des Cachens erhält.
Die Ergebnisse konnten wir dann per JavaScript im Browser parsen.
Ja, wir senden mehr Daten als nötig, aber wir gewinnen in Bezug auf Verarbeitungsgeschwindigkeit und Reaktionszeit.
Zerstöre die Vorstellung, dass WordPress nur langsam ist
Dies sind nur einige Ratschläge, die Entwickler beim Codieren für WordPress berücksichtigen sollten.
Manchmal vergessen wir, dass unser Plugin oder Theme möglicherweise mit anderen Plugins zusammenleben muss oder dass unsere Website möglicherweise von einem Hosting-Unternehmen bereitgestellt wird, das Hunderte oder Tausende anderer Websites mit einer gemeinsamen Datenbank bedient.
Wir konzentrieren uns nur darauf, wie das Plugin funktionieren soll, und nicht darauf, wie es mit dieser Funktionalität umgeht oder wie man es auf effiziente Weise macht.
Aus dem oben Gesagten ist klar, dass die Hauptursachen für schlechte Leistung in WordPress schlechter und ineffizienter Code sind. WordPress bietet jedoch alle notwendigen Funktionalitäten durch seine verschiedenen APIs, die uns helfen können, viel leistungsfähigere Plugins und Themen zu erstellen, ohne die Geschwindigkeit der gesamten Plattform zu beeinträchtigen.