Praxistipps zur Steigerung der Website-Performance: High-Performance-Websites
Von 2003 bis 2009 wuchsen Websites von durchschnittlich 97 KB um mehr als den Faktor 4 auf 412 KB [1]. Dieser Zuwachs resultiert hauptsächlich aus komplexen JavaScript-Libraries sowie multimedialen Inhalten. Gleichzeitig nahm die globale Internetgeschwindigkeit ab: 2009 fiel die Internet-Geschwindigkeit weltweit um 11 Prozent [2]. Grund ist die intensivere Belastung bestehender Netze durch Streaming-Media, während weltweit weniger in den Netzausbau investiert wurde.
Neben der verstärkten Nutzung konventioneller Internet-Anbindungen hat der Einsatz des mobilen Breitband-Internets zugenommen. Nach aktuellen Schätzungen surfen alleine in Deutschland 1 Million Menschen über Mobilfunknetze. Dadurch ist eine neue Herausforderung für Web-Developer entstanden: Vergleichsweise schwache CPUs der Endgeräte und stark variierende Bandbreite erfordern große Sorgfalt bei der Performance-Optimierung.
Während Websites immer größer werden und das Netz immer stärker ausgelastet wird, werden die Benutzer immer versierter im Umgang mit dem Medium Internet. Für fast jede vorstellbare Aufgabe wählen sie bewusst aus einer Vielzahl an verfügbaren Diensten. In dieser konkurrenzbetonten Netzwelt ist erfolgreiches Interaktionsdesign oftmals der entscheidende Faktor für Erfolg oder Scheitern von Webangeboten. Performance ist dabei ein Kernelement erfolgreicher Benutzer-Interaktion: Ist eine flüssige Interaktion nicht möglich, werden Benutzer frustriert und wenden sich alternativen Angeboten zu.
Bereits 100ms entscheiden
Benutzer reagieren bereits auf feine Performance-Unterschiede, wie aktuelle Untersuchungen der Betreiber einiger der meistgenutzten Websites weltweit zeigen. So experimentierte Amazon mit einer gezielten Verzögerung von 100ms bei der Auslieferung der Produktseiten, um den Einfluss auf die Verkaufszahlen zu messen. Das Ergebnis: ein Prozent weniger Einkäufe.
Yahoo verzögerte testweise die Auslieferung der Startseite um 400ms. Resultat: Neun Prozent aller Benutzer schlossen die aufgerufene Yahoo-Startseite, noch bevor diese komplett geladen war [3]. In einer Kooperation zwischen Google und Microsoft Bing analysierten die beiden Marktführer im Suchmaschinen-Sektor den Einfluss von Ladezeiten auf die Benutzung ihrer Websites. Eine Verzögerung um 500ms bei der Auslieferung der Suchergebnisse führte zu 20 Prozent weniger Suchanfragen, insbesondere bei Folgesuchen [4].
Shopzilla, eine Shopping-Suchmaschine, unterzog die eigene Website einer ausführlichen Performance-Optimierung und konnte dadurch die Ladezeit um ganze 3,5 Sekunden senken. Durch die flüssigere Interaktion stiegen die Umsätze um 12 Prozent [5]. Netflix, ein Video-Streaming-Dienst, optimierte sein Angebot mit Fokus auf die Reduktion von HTTP-Requests und besseres Caching und konnte somit seinen Traffic um 50 Prozent senken – eine signifikante Kostenersparnis [6].
Vorteile der Optimierung
Anhand dieser Untersuchungen von Website-Performance lassen sich folgende Vorteile von High-Performance-Websites ausmachen:
- Mehr Benutzer
- Erhöhte Interaktion
- Vertrauensvorschuss
- Niedrigere Betriebskosten
Für die Performance-Optimierung ist es nötig, sinnvolle Bereiche zur Bearbeitung zu erkennen und deren Potenzial einzuschätzen. Im Folgenden erfahren Sie, dem Potenzial nach geordnet, was Sie bei der Performance-Optimierung besonders voran bringt.
GZip
Mit GZip können Inhalte einer Website serverseitig vorkomprimiert und dadurch schneller ausgeliefert werden: Geeignet sind HTML, CSS und JavaScript, aber auch nicht direkt performancerelevante Inhalte wie RSS-Feeds lassen sich komprimieren, um die zu übertragende Datenmenge zu reduzieren. Das Entfernen von Whitespace und Kommentaren aus CSS und JavaScript noch vor dem Zippen, das so genannte Minifying, spart zusätzlich Platz und damit Bandbreite [7].
Obwohl fast alle moderneren Browser den Empfang von komprimierten Daten unterstützen, setzen immer noch viele Website-Betreiber auf eine unkomprimierte Datenübertragung. Der Umstieg lohnt sich jedoch: GZip kann die Zeit bis zum vollständigen Seitenaufbau halbieren.
HTTP-Requests
Nach dem Einsatz von GZip ist die Reduktion von HTTP-Requests die effektivste Möglichkeit zur Performance-Optimierung. HTTP-Requests werden von allen Einzelelementen einer Website wie HTML, CSS, JavaScript-Libraries, Bildern, Flash-Objekten, Videos und mehr ausgelöst. Jedes Element erzeugt zum Laden ein HTTP-Request.
Der aktuelle Durchschnitt an HTTP-Objekten liegt bei 60 je Website. Browser können jedoch viel weniger Objekte pro Domain gleichzeitig abrufen: Firefox 2 und Internet Explorer 6/7 (IE) können nur zwei Objekte, Safari kann vier, Chrome, der IE8 und Firefox 3 können sechs und Opera kann acht Objekte pro Domain abrufen [8]. Alle weiteren benötigten Objekte kommen in eine Warteschlange. Erschwerend kommt hinzu, dass Webserver oftmals aus Sicherheitsgründen nur 256 HTTP-Requests gleichzeitig zulassen. Wird dieses Limit durch viele gleichzeitig aktive Benutzer erreicht, erscheint der Webserver für alle weiteren Anfragen temporär unerreichbar.
HTTP-Requests lassen sich reduzieren, indem man JavaScript-Libraries und CSS zu jeweils einer Datei zusammenfasst. Außerdem kann man häufige Navigationselemente, Buttons und Icons zu einem großen zusammenhängenden Bild vereinen, einem CSS-Sprite [9]. Dadurch reduzieren sich die vielen HTTP-Requests für Navigationsgrafiken auf einen einzelnen Request.
Expire-Header
Viele Webserver ermöglichen standardmäßig nicht die optimale Nutzung des Browsercaches. Oftmals wird der Expire-Header, der benötigt wird, um neu zu ladende Elemente von denjenigen zu unterscheiden, die aus dem Cache des Besuchers genutzt werden können, nicht gesetzt. Man sollte also überprüfen, ob der Webserver den Expire-Header korrekt einsetzt.
Außerdem empfiehlt es sich, für statische Inhalte ein Verfallsdatum weit in der Zukunft zu wählen, um möglichst oft Cache-Inhalte zu nutzen, statt diese erneut zu senden. Um Inhalte wie Header-Grafiken, CSS und JavaScript, die sich eventuell geändert haben, trotzdem neu laden zu können, sollte man eine Versionierung bei der Benennung von Dateien einführen. Die Version kann im Dateinamen („bsp-001.png“) oder als Anhang („bsp.png?version=001“) codiert sein. Durch Änderung der Versionsnummer forciert man ein Neuladen des Elements, sodass alle Besucher die aktualisierte Version erhalten und niemand veraltete Inhalte sieht.
Jedes Element, das aus dem Cache des Besuchers kommt und nicht erneut gesendet werden muss, spart bei jedem weiteren Seitenaufruf Performance ein. Daher sollte man das Caching möglichst optimal ausnutzen [10].
Load-Sharing
Das Limit von HTTP-Requests greift pro Domain. Durch Verteilung der Inhalte einer Website auf mehrere Domains oder Server, das so genannte Load-Sharing, kann man dieses Limit umgehen.
Wer nicht viel Budget zu Verfügung hat, sollte die Aufteilung auf Subdomains auf dem gleichen Server einsetzen, zum Beispiel „code.beispiel.de“ für JavaScript und CSS, „images.beispiel.de“ für Grafiken und „interactive.beispiel.de“ für dynamische Inhalte. Dabei sollte man nicht zu viele verschiedene Subdomains benutzen, da jede zusätzliche Domain via DNS aufgelöst werden muss und dadurch zusätzlich Zeit verbraucht. Das Verhältnis von Zeitersparnis zu zusätzlichem Zeitverbrauch muss stimmen.
Performanter, aber auch etwas kostenintensiver, ist die Aufteilung auf mehrere Server. Durch die Verteilung von Rechenlast und Bandbreite steigt die Performance signifikant. In einem solchen Setup lässt sich auch eine Optimierung des HTTP-Protokolls einsetzen. HTTP 1.1 lässt nur zwei gleichzeitige, dafür aber persistente Verbindungen je Client zu – eine Entwicklung, die dem größeren Datenaufkommen durch Streaming zuzuschreiben ist. HTTP 1.0 hingegen eignet sich nicht für persistente Verbindungen, es erlaubt aber vier gleichzeitige Verbindungen pro Client, was den Download statischer Inhalte beschleunigt. Hat man für die Auslieferung einer Website drei unterschiedliche Server zur Verfügung, kann man die zwei Server, die statische Inhalte ausliefern, auf HTTP 1.0 downgraden und nur auf dem dritten Server für dynamische Inhalte HTTP 1.1 einsetzen [11].
Für große Websites mit entsprechendem Budget kommt auch ein Content-Delivery-Network (CDN) in Frage. Solch ein Netzwerk aus verteilten Servern hält Kopien der Website-Inhalte an verschiedenen Standorten vor, um sie dem Besucher anhand seiner geographischen Position auszuliefern und somit die Abrufzeiten der Website zu verkürzen. Großprojekte wie Wikipedia setzen sehr ausgeklügelte CDNs ein, um Inhalte an die weltweiten Besucher auszuliefern [12].
Problematisch bei mehreren Servern oder einem CDN sind ETags. Mit ihnen wird geprüft, ob die Version einer Datei im Cache des Besuchers der Version auf dem Server entspricht. Ist die Datei identisch, wird sie aus dem Cache genutzt, falls nicht, wird sie neu gesendet. Wird mehr als ein Server zur Inhaltsauslieferung genutzt, so können ETags, die auch den jeweiligen Ursprungsserver beinhalten, nicht korrekt funktionieren und es werden viele Daten übertragen, die schon im Cache vorliegen. In diesem Fall sollte man ETags deaktivieren. Die Cache-Überprüfung fällt dann zurück auf den „Last modified“-Check, der für ein solches Setup ausreicht.
Google hat einen neuen kostenlosen Ansatz für die Last-Verteilung und optimale Cache-Ausnutzung: die Google AJAX Libraries API. Google hostet auf eigenen Servern beliebte JavaScript-Libraries und ermutigt Website-Betreiber, diese einzubinden. Hat ein Benutzer bereits Websites besucht, die Google-Server für JavaScript-Libraries nutzen, so kann die Library im Cache des Benutzers genutzt werden. Dies erhöht die Performance [13].
Auch der kommende HTML5-Standard ist für Performance interessant: HTML5 bringt erstmals feste Parsing-Regeln für Browser mit sich. Durch dieses standardisierte Parsing verarbeiten Browser-Engines HTML5 bis zu 5 Prozent schneller [14].
CSS – Stylish und performant
Auch bei CSS gibt es signifikante Performance-Unterschiede: Die performantesten CSS-Selektoren sind das klassische ID (#) und Class (.). Der Einsatz komplexerer CSS-Selektoren wie Wildcard-Selector (*), Descendant-Selector (>) oder CSS3-Selector geht zu Lasten der Performance, denn die Browser-Engines brauchen wesentlich länger, um sie zu verarbeiten. Daher sollte man für eine High-Performance-Website auf komplexe CSS-Selektoren verzichten und modulares CSS mit wiederverwendbaren Klassen schreiben [15].
JavaScript-Expressions in CSS, wie man sie zum Beispiel zur Simulation von „min-width“ im IE nutzen kann (expression(document.body.clientWidth > 960)?"960px" : "auto";), sind ebenfalls ein Performance-Problem. Die Verarbeitung solcher Expressions kostet bei jedem Seitenaufruf erneut Zeit.
Auch „@import“ für die Referenzierung von CSS sollte man meiden, denn es blockiert je nach Browser-Engine den Ladevorgang, bis die referenzierte Datei vollständig geladen und geparst wurde. „@import“ sollte man also weder im Header eines HTML-Dokuments noch innerhalb eines Stylesheets verwenden, um ein anderes Stylesheet zu laden.
JavaScript
Der Aufruf des idealerweise bereits zu einer einzelnen Library zusammengefassten JavaScripts sollte aus dem Header an das Ende des HTML-Dokuments verschoben werden: Die ideale Position ist direkt vor dem schließenden </body>. Dadurch wird das gesamte HTML-Grundgerüst vor den Skripten geladen.
Außerdem kann man das „defer“-Attribut einsetzen: Das JavaScript wird so als nicht direkt relevant für die Anzeige von Inhalten gekennzeichnet und erst zum Ende des Seitenaufrufs hin ausgeführt [16]. Das „defer“-Attribut wird derzeit zwar nur vom Internet Explorer ab Version 4 und von Firefox 3.5 unterstützt, eine breitere Browserunterstützung ist aber absehbar.
Grafiken
Grafiken bieten viel Potenzial zur Reduktion der zu übertragenen Datenmenge: Ein 300-KB-Foto kann ohne erkennbaren Qualitätsverlust auf 40 KB komprimiert werden. Zur Bildoptimierung gibt es verschiedene Methoden: manuelle Bildoptimierung via Photoshop/GIMP, halbautomatische Optimierung via Web-Apps wie PunyPNG oder serverseitige Optimierung und Caching mit dem Apache-Modul „moddims“ oder mit Chronjobs (z. B. für „optipng“).
Jetzt aber los!
Mit den aufgezeigten Methoden lassen sich Ladezeitverbesserungen von bis zu 75 Prozent erreichen. Das reduziert nicht nur die Betriebskosten und die Serverlast, sondern sorgt auch für mehr Umsatz, mehr Besucher und wirkt vertrauensbildend.
Schön aber alles sehr basic, etwas erweitertes über caching Lösungen wäre nett gewesen (Varnish usw.)