Home Menü

WordPress Performance durch Reduzierung von HTTP Requests steigern

Die Ladezeit einer Webseite wird maßgeblich dadurch beeinflusst, wie viele HTTP Requests beim Aufruf der Seite an den Webserver gesendet werden. So einfach das klingt, so wenig wird es in der Praxis vor allem bei WordPress Seiten beachtet. Dieser Artikel zeigt Ihnen, wie Sie die Anzahl der HTTP Requests reduzieren können und dadurch die Performance Ihrer WordPress Webseite maßgeblich steigern.

Dieser Artikel ist Teil der Guideline High-Performance Websites mit WordPress.

Viele Webseiten-Betreiber fragen sich, warum Ihre Seite dem Anwender immer noch recht langsam angezeigt wird, obwohl die Download-Geschwindigkeit der Besucher mittlerweile schon im zwei bis dreistelligen Megabit-Bereich pro Sekunde liegt. Diese Frage ist recht einfach zu beantworten, wenn man die Grundprinzipien des HTTP-Protokolls etwas näher betrachtet.

Das HTTP-Protokoll

Beim Hypertext Transfer Protocol (HTTP) handelt es sich um ein Client/Server Protokoll. Immer wenn Sie in Ihrem Browser eine Webseite aufrufen, beispielsweise www.blog-it-solutions.de, sendet Ihr Browser einen HTTP-Request für diese spezielle URL an den Server der Webseite. Dieser antwortet dann seinerseits mit einem HTTP Response. Generell gibt es verschiedene Arten von HTTP Requests wie GET, POST, HEAD, PUT, DELETE, OPTIONS und TRACE. Der gängigste Typ ist der HTTP GET Request, auf welchen wir uns im Folgenden auch konzentrieren werden. Hinter dem ganzen Ablauf steckt keine Zauberei, im Gegenteil, dass HTTP Protokoll ist sehr einfach gehalten und sendet die Daten im Klartext (im Gegensatz zu HTTPS).

Ein typischer HTTP GET Request zur Startseite von Blog IT-Solutions enthält eine URL gefolgt von Header-Informationen und sieht in gekürzter Form in etwa so aus:

GET / HTTP/1.1
Host: www.blog-it-solutions.de
User-Agent: Mozilla/5.0 (...) Gecko/20100101 Firefox/24.0

Diese Anfrage wird vom Server mit einem HTTP Response, bestehend aus einem HTTP Status Code, Headern und dem Body, der den eigentlichen HTML-Code der Seite bereitstellt, beantwortet:

HTTP/1.1 200 OK
Date: Sun, 20 Oct 2013 23:47:20 GMT
Server: Apache
Content-Type: text/html; charset=UTF-8
Last-Modified: Sun, 20 Oct 2013 23:29:41 GMT
Content-Length: 10100

Body-Content ...

Soweit so gut. Jetzt hat der Browser die Startseite per HTTP Response vom Webserver erhalten. Im nächsten Schritt verarbeitet der Browser diese Seite und versucht die dort enthaltenen Inhalte wie beispielsweise CSS-Dateien, JavaScript-Dateien, Bilder etc. ebenfalls vom Webserver per HTTP GET Request anzufordern.

Jeder dieser Requests benötigt Zeit. In WordPress sehen der Ablauf und die Verarbeitung eines Requests und des dazugehörigen Response wie folgt aus:

  1. DNS Lookup: Zeit die benötigt wird um die Domain (www.blog-it-solutions.de) zur dazugehörigen IP-Adresse (91.250.114.144) aufzulösen.
  2. Initial Connection: Zeit die vergeht, bis Ihr Computer eine TCP/IP Verbindung mit dem Server öffnet. Ab HTTP 1.1 sind persistente Verbindungen möglich, die von verschiedenen Seitenelementen wieder benutzt werden können, was die Initial Connection Zeit bei einer Wiederbenutzung auf 0 senkt.
  3. Time to First Byte: Der Browser sendet einen HTTP-Request an den Webserver welcher die Anfrage anschließend verarbeitet. Wird auf eine WordPress-Seite zugegriffen, beginnt WordPress zu arbeiten: PHP-Files laden, Zugriff auf die Datenbank, Theme und Plugins laden, Rendering der Seite etc. Sind diese Vorgänge abgeschlossen antwortet der Server mit einem HTTP-Response und der Content Download beginnt.
  4. Content Download: In dieser Zeit wird die jeweilige Datei (CSS, JavaScript, Bilder oder HTML) vom Webserver an den Browser übertragen.
  5. Im letzten Schritt beginnt der Browser die erhaltenen Daten zu verstehen und zu verarbeiten. Weitere Dateien werden gegebenenfalls per HTTP GET Request angefordert und der Prozess beginnt von vorne.

Sehr schön zu sehen ist dieser Prozess eines einzelnen GET Requests im Wasserfallmodell, welches beispielsweise von webpagetest.org generiert wird:

Hinweis: Laut Information von WebPagetest wird die Verarbeitung durch WordPress, wie in Punkt 3 erläutert, nur im ersten nicht-weitergeleiteten Request im Wasserfall-Modell angezeigt. Das heißt konkret, wenn Sie auf der Seite von WordPress nach Optimierungspotential Ausschau halten, müssen Sie nur in die Time to First Byte des ersten nicht-weitergeleiteten Requests schauen.

Sie sehen in dem gezeigten Wasserfallmodell auch deutlich, dass es eigentlich keinen großen Unterschied macht, wie schnell die Internetverbindung Ihrer Besucher ist. Die Zeit die für den Content Download der einzelnen Komponenten benötigt wird ist im Vergleich zur Zeit die die anderen Vorgänge benötigen schon fast zu vernachlässigen.

Reduzierung von HTTP Requests

Die beste Methode um mit der Reduzierung von HTTP Requests zu starten ist die Analyse der einzelnen Inhalte, die am meisten Anfragen verursachen. Dies können Sie beispielsweise mithilfe von WebPagetest unter Content Breakdown einsehen. Für Blog IT-Solutions zeigt die Grafik deutlich, dass der Großteil der Requests (über 60 %) von Bildern verursacht wird.

Bilder

Bei Bildern gibt es im Grunde drei verschiedene Möglichkeiten HTTP Requests zu reduzieren, wobei dieser Artikel nur auf die gängigsten, die letzten beiden, eingeht:

  • Image Maps
  • CSS Sprites
  • Inline Images

CSS Sprites

Bei dieser Technik werden mehrere Bilder einfach in einem Bild zusammengefügt. Haben Sie beispielsweise 10 kleinere Bilder die Sie im Layout Ihrer Webseite verwenden, können Sie diese in einem Bild zusammenfügen und so die Anzahl der benötigten Anfragen von 10 auf 1 reduzieren. Auf Blog IT-Solutions setzten wir ein solches CSS-Sprite bei den Social Media Icons eingesetzt:

Anstatt die Bilder wie vorher direkt per IMG-Tag in das Layout einzufügen, müssen Sie nun den Weg über die CSS Eigenschaften background-image und background-position gehen. Diese können Sie bei allen Elementen anwenden, welche die genannten Eigenschaften unterstützen, beispielsweise SPAN oder DIV.

Ein gutes Praxisbeispiel finden Sie auf der Webseite von Steve Souders. Lassen Sie sich auf den einzelnen Seiten einfach den Quellcode – im speziellen im Bereich der 5 Bilder im gelben Kasten – anzeigen, um den Unterschied zu erkennen. Zudem finden Sie auf den einzelnen Seiten auch direkt eine Messung der Ladezeiten. Normale IMG-Tags und Optimierung mit CSS-Sprites.

Steve Souders schreibt in seinem Buch High Performance Web Sites: 14 Steps to Faster-Loading Web Sites, dass durch den Einsatz von CSS-Sprites im Vergleich zu separaten Bildern die Ladezeit in der Regel um etwa 57 % reduziert werden kann.

Viele mögen sich an dieser Stelle vielleicht fragen, wie aufwändig die Erstellung von CSS-Sprites ist. Ich kann Sie beruhigen, der Aufwand ist nicht sehr groß, da es mittlerweile schon zahlreiche Tools gibt, die Sie beim Erstellen von CSS-Sprites unterstützen. Eines davon stammt vom vorher erwähnten Autor und heißt SpriteMe.

Neben dem Vorteil, dass Sie durch CSS Sprites die Anzahl der HTTP Requests reduzieren, verringern Sie auch gleichzeitig die Downloadgröße. Obwohl zwischen den einzelnen Bildern im CSS Sprite jede Menge Leerraum ist, der das Bild sehr aufgebläht erscheinen lässt, sind CSS Sprites kleiner als die ursprünglichen Bilder. Der Grund: Durch das Zusammenfügen der Bilder wird der Overhead der einzelnen Bilder reduziert (Farbtabellen, Formatinformation, etc.).

Inline Images

Eine weitere Möglichkeit zur Reduzierung von HTTP Requests bei Bildern sind Inline Images. Hierbei macht man sich das HTTP URI Scheme data: zu nutze. Im Grunde funktioniert das wie folgt: Anstatt das Bilder von einer bestimmten URI zu laden wird es einfach als Base64-Code (Konvertierung eines Bildes in Base64) in den HTML oder CSS-Code eingefügt:

Alter Code:

<img src="https://blog-it-solutions.de/Bild.png" alt="Blog IT-Solutions" />

Neuer Code (nicht vollständig):

<img alt="Blog IT-Solutions" src="data:image/png;base64,iVBORw0KGgoAAAANSU..." />

Diese Methode ist im Vergleich zu CSS-Sprites einfacher, bringt aber auch einigen Nachteilen mit:

  • Das data: URI Scheme wird bis einschließlich Internet Explorer 7 nicht unterstützt
  • Ist das data: URI direkt im HTML eingebettet, wird es nicht gecacht. Dies kann vor allem bei Bildern des Layouts sehr unvorteilhaft sein. Die Lösung: Das data: URI nicht in den HTML-Code sondern in eine externe CSS-Datei mit der Background-Eigenschaft einbetten, da CSS-Dateien gecacht werden können.
  • Durch die Umwandlung in das benötigte Base64-Format wird die Datei um etwa 1/3 größer.
  • Je nach Browserversion werden Inline-Images nur bis zu einer gewissen Größe unterstützt.

Abschließend stellt sich noch die Frage, wann man diese Inline-Images verwenden soll? Die Antwort auf diese Frage ist nicht ganz einfach, da immer Ihre individuellen Anforderungen berücksichtigt werden müssen. Möchten Sie beispielsweise die Kompatibilität Ihrer Webseite mit dem Internet Explorer Version 7 sicherstellen, so sind Inline-Images für Sie keine Lösung.

Aus Performance-Sicht kann man allerdings eine Empfehlung für Inline-Images abgeben. Laut Steve Souders benötigt jeder zusätzliche GET-Request im weltweiten Durchschnitt etwa 200ms. Können Sie nun auf einen zusätzlichen GET-Request verzichten, indem Sie das Bild direkt im Code einbinden, so lohnt es sich in den meisten Fällen sogar dann, wenn Sie relativ große Bilder als Inline-Image verwenden.

Beispiel: Auf Blog IT-Solutions habe wir das Logo mit einer Größe von 6.4 KB als Inline-Image direkt in die CSS-Datei eingebettet. Dadurch ist die Größe der CSS-Datei von 15.2 KB auf 21.6 KB angestiegen. Anders als erwartet, wurde das Bild durch die Konvertierung ins Base64-Format nicht um 1/3 größer, was mit der aktivierten GZIP-Komprimierung auf dem Server zusammenhängen könnte. Durch den eingesparten GET-Request des Logos konnte die Ladezeit um etwa 90ms verringert werden, die Download-Zeit der CSS-Datei ist hingegen nur um etwa 10-20ms (je nach Internet-Geschwindigkeit) angestiegen. Das Ergebnis: Durch die Platzierung der Grafik als Base64-Code direkt in der CSS-Datei konnte die Ladezeit der Seite um etwa 70-80ms verringert werden (ohne Berücksichtigung der Möglichkeit, Ressourcen im Browser parallel zu laden).

Da das Thema der Inline-Images vor allem mit Bezug auf die Performance sehr interessant ist, wird es in einem späteren Artikel noch einmal im Detail erläutert.

Ein sehr nützliches und überaus empfehlenswertes WordPress Plugin, welches Blog IT-Solutions auch mit Verbesserungen und einer deutschen Übersetzung ab Version 1.7 unterstützt hat, ist Autoptimize. In den Einstellungen dazu kann unter anderem festgelegt werden, ob alle Background-Images die kleiner als 2,5 KB sind automatisch mit dem data: Scheme ersetzt werden sollen:

Alleine durch Aktivierung dieser Option konnten auf Blog IT-Solutions insgesamt 7 HTTP GET Requests eingespart werden.

JavaScript und CSS zusammenfügen

WordPress liefert im Standard bereits zahlreiche JavaScript und CSS-Dateien aus. Haben Sie sich noch für ein individuelles Theme entschieden und im Hintergrund noch Plugins installiert, so kann es gut und gerne vorkommen, dass sie über 10 verschiedene CSS und JavaScript Dateien ausliefern. Das bedeutet: Über 10 HTTP GET Requests.

Da wäre es natürlich gut, wenn man alle JavaScript-Dateien zu einer JavaScript-Datei zusammenfassen könnte. Ebenso wäre es gut, wenn das gleiche auch beim CSS-Code möglich wäre. Zum Glück gibt es dafür unter WordPress wieder zahlreiche Plugins. Einer meiner früheren Favoriten hierzu war WP Minify. Das Plugin wurde allerdings seit über einem Jahr nicht mehr aktualisiert und Support gibt es leider auch keinen mehr. Zudem hatten wir in Zusammenhang mit dem Cache-Plugin WP SuperCache (dazu in einem späteren Artikel mehr) mit einigen Kompatibilitätsproblemen zu kämpfen. Mein neuer Favorit in diesem Bereich ist das bereits erwähnte Plugin Autoptimize, weshalb wir den Entwickler auch mit Verbesserungsvorschlägen und Tests unterstützen. Der Support ist zudem mehr als vorbildlich.

Nach der Installation stehen Ihnen zwei Optionen zur Verfügung, wie Sie den JavaScript-Code in eine Datei und den CSS-Code in eine andere Datei zusammenfassen können und dadurch die Anzahl der GET Requests verringern. Zusätzlich wird der Code auch gleich noch komprimiert, was Downloadzeit einspart:

Da das Plugin mit den erwähnten Optimierungsoptionen auf Blog IT-Solutions bereits vor dieser Artikelserie eingesetzt wurde, konnten im aktuellen Selbsttest keine GET Requests eingespart werden. Werden die Optionen zur Optimierung allerdings deaktiviert, so steigt die Anzahl der benötigten GET Requests um 17 an.

Ist-Zustand nach Reduzierung von HTTP Requests

Auf Blog IT-Solutions setzten wir in diesem Teil der Optimierung vor allem auf eine Detail-Analyse der einzelnen HTTP Requests. Da bereits vorher das Plugin Autoptimize eingesetzt wurde, konnten wir durch Anpassung der Optionen nicht mehr ganz so viele Requests einsparen, wie das bei Ihnen vielleicht der Fall sein könnte.

Im folgenden eine Übersicht der eingesparten HTTP GET Requests:

  • Durch Aktivierung von data:URIs (Inline-Images) in Autoptimize konnten 7 GET Requests eingespart werden.
  • Teile der WordPress ThickBox Funktionalität wurden aufgrund von Altlasten auf der Startseite noch geladen. Die Funktionalität wurde deaktiviert und 1 GET Request eingespart.
  • Der Header ist nun als Inline-Image in der CSS-Datei hinterlegt (1 GET Request).
  • Die Jetpack JavaScript-Datei für hochauflösende Gravatars (devicepx-jetpack.js) wurde entfernt.
  • 2 weitere GET Requests konnten dadurch eingespart werden, dass manche Plugins nicht mehr global geladen werden sondern nur noch bei Bedarf. Realisiert wurde dies mit dem WordPress Plugin Organizer.

Durch diese Maßnahmen konnten insgesamt 12 HTTP Requests eingespart werden. Zusätzlich wurde für den Test von der Startseite die AdSense-Werbung entfernt, da abhängig von der jeweils geladenen Werbung die Ergebnisse des Tests ständig verfälscht wurden. Durch das Entfernen konnte die Anzahl der Anfragen noch einmal um 10 reduziert werden, was ganz klar zeigt, dass der Einsatz von AdSense die Performance einer Webseite signifikant negativ beeinflusst.

Document Complete

VorherNachherVeränderung
ZeitRequestsBytesZeitRequestsBytesZeitRequests
Empty Cache2.886s45521 KB1.574s23367 KB-45 %-22
Primed Cache0.958s1076 KB0.697s873 KB-27 %-2

Erläuterung: Der Test zeigt ganz klar, welch großen Einfluss die Anzahl der HTTP Requests auf die Performance einer Webseite hat. Wird die Anzahl der HTTP Requests halbiert, senkt sich auch die Ladezeit um etwa 50 Prozent. Wird der Test mit einer Google AdSense Anzeige auf der Startseite durchgeführt, dann erhöht sich die Anzahl der Requests um ca. 10 und die Ladezeit erhöht sich ebenfalls um ca. 600 – 800ms.

Fully Loaded

VorherNacherVeränderung
ZeitRequestsBytesZeitRequestsBytesZeitRequests
Empty Cache2.955s47525 KB1.642s23525 KB-44 %-24
Primed Cache1.152s1076 KB0.769s876 KB-33 %-2

Google Pagespeed

VorherNachher
Google PageSpeed Mobil7378
Google PageSpeed Desktop8489

YSlow

VorherNachher
YSlow Punkte8183
YSlow GradeBB

Fazit

Wie sich im Verlauf der Optimierung gezeigt hat, ist die These von Steve Souders richtig, dass die Reduzierung von HTTP Requests das höchste Einsparpotential an Ladezeit mit sich bringt. Mit WordPress wird es dem Webseitenbetreiber zum Teil sogar sehr einfach gemacht, die HTTP Requests innerhalb von nur wenigen Minuten durch die Installation eines Plugins um zum Teil 30-50 Prozent zu senken. Unsere Empfehlung: Nutzen Sie diese einfache Möglichkeit die Performance Ihrer WordPress Webseite durch Reduzierung von HTTP Requests zu steigern.

Getestet unter WordPress 3.6(.1) und Autoptimize 1.7

Veröffentlicht von Josef Seidl

Josef Seidl hat an der TU München und der Stanford University Wirtschaftsinformatik studiert, bevor er mit INNOSPOT sein eigenes Unternehmen gründete. Er ist begeistert von Technik, schätzt performante Webseiten und ist gerne in den Bergen unterwegs. Zu finden ist er auch bei LinkedIn und privat bei Twitter.