Im 1. Teil des Artikels wurde bereits darauf eingegangen, weshalb die Performance von Websites von Bedeutung für Suchmaschinen, Usability und Conversions wichtig ist sowie Möglichkeiten und Tools zur Messung der Ladegeschwindigkeit dargestellt. Dieser Artikel soll nun zeigen, welche Faktoren die Ladezeit einer Website beeinflussen und Maßnahmen zur gezielten Optimierung vorstellen.

Grundsätze zur Optimierung der Seitenperformance

Die Seitenladezeit wird durch eine Reihe verschiedener Faktoren bestimmt, z. B.:

  • Anzahl der gesamten HTTP-Requests
  • Anzahl der gleichzeitigen HTTP-Requests
  • Größe der abzurufenden Daten 

Jeder Abruf eines Objektes aus dem Quellcode erfordert einen HTTP-Request. Diese Requests werden zum Teil gleichzeitig aber auch nacheinander abgearbeitet. Die Anzahl gleichzeitiger HTTP-Requests wird durch Webserver und Browser in der Regel auf einige wenige beschränkt. Gemäß HTTP 1.1 Spezifikation sollten Browser nicht mehr als 2 gleichzeitige Verbindungen zu einem Host erlauben. Die Daten müssen zu einem großen Teil nacheinander abgerufen werden und verzögern das Laden der Seite. Beispiel: Eine Webseite erlaubt bis zu 2 gleichzeitige Verbindungen und verfügt über 8 Bilder. Beim Abruf der Daten werden 2 Bilder gleichzeitig geladen, die übrigen 6 werden in die Warteschlange gelegt und rücken jeweils nach, sobald ein Bild abgearbeitet ist. Zur Anzahl gleichzeitiger HTTP-Requests kommt die Größe der abzurufenden Daten. Je höher diese ist, desto länger wird die Ladezeit. Wie die Optimierung dieser Faktoren in der Praxis aussieht, sollen nachfolgende Beispiele zur Leistungssteigerung zeigen.

Reduzierung der Anzahl an HTTP-Requests

Um die Anzahl an HTTP-Requests insgesamt zu reduzieren, gibt es mehrere Wege: das Entfernen, das Zusammenfügen oder das Cachen von Dateien.

Zusammenfügen von Grafiken

Erstellung von CSS Sprites

CSS-Sprites sind eine gute Möglichkeit, um häufig genutzte Grafiken zu einer einzigen Datei zusammenzufügen. Dabei werden einzelne Bilder zu einer Grafik zusammengefasst, mittels CSS wird der jeweilige Teil des Bildes angesteuert. Alle Bilder, die im Sprite zusammengefasst sind, verfügen über die gleiche Hintergrundgrafik im CSS, unterscheiden sich aber in der Position (background-position). Ein Beispiel für die Positionierung der Elemente im CSS:

ul li a.facebook {
background-position:0 0;
}

ul li a.linkedin {
background-position:0 -36px;
}

ul li a.twitter {
background-position:0 -96px;
}

Der entscheidende Vorteil dieser Maßnahme ist, dass lediglich eine Datei abgerufen werden muss. Besonders Elemente, die auf vielen Seiten genutzt werden, sollten in CSS-Sprites kombiniert werden. Ein Beispiel für die Nutzung von CSS-Sprites zeigt sich bei Facebook:

CSS Sprites Facebook

CSS Sprites Facebook

CSS-Sprites werden beim Webstandard ausführlicher erklärt, das Tool SpriteMe kann zur Erstellung von Sprites genutzt werden.

Optimierung des Caching durch Setzen von Expires Headern

Zur weiteren Minimierung der HTTP-Requests kann die Häufigkeit reduziert werden, in der ein Browser Informationen von einer Website neu abruft. Bei dieser Optimierungsmaßnahme wird über die .htaccess eine Zeitspanne gesetzt, innerhalb derer eine Information nicht erneut abgerufen wird. Gerade bei Daten, die sich seltener ändern, wie z. B. das Logo einer Website, CSS- oder JS-Dateien, ist das Setzen von Expiration Dates eine gute Möglichkeit der Performance-Optimierung. Ein Beispiel für das Setzen von Expiration Dates:


ExpiresDefault "<base> [plus] {<num> <type>}*"
ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"

Wobei für “base” entweder access, now oder modification einzusetzen ist. “plus” ist optional, “num” erfordert einen Integer-Wert und “type” eine Zeitinformation (years, months, weeks, days, hours, minutes, seconds).
Ein konkretes Beispiel für das Setzen von Expiration Dates über die .htaccess:


<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 week"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Durch diese Anweisungen in der .htaccess wird die Gültigkeit der Dateien standardmäßig auf eine Woche in der Zukunft gesetzt. Dateitypen wie .jpg, CSS- oder JS-Dateien erhalten eine längere Gültigkeit von einem Monat ab dem Abruf der Seite. Geprüft werden kann die Angabe des Expired Dates z. B. im Web Sniffer oder über das Firefox/Chrome Add-On Page Speed, das im 1. Artikel vorgestellt wurde.

Weitere Informationen zu Expiration Dates finden sich auch auf dem Blog Webmaster-Zentrale.

Zusammenfassung von CSS- und JS-Code

Häufig finden sich im HTML-Quellcode CSS- oder JavaScript-Code. Es entspricht jedoch nicht dem Grundsatz der Trennung von Struktur und Inhalt, CSS- oder JS-Code direkt im HTML-Quelltext einzubinden. Ein Auslagern solcher Elemente in eigenständige Dateien ist nicht nur für die Performance von Vorteil, sondern auch standardkonform und reduziert Wartungsaufwand.

Ein weiteres Problem bei CSS-Anweisungen im Quellcode ist, dass sie nicht nur beim Seitenaufruf abgerufen werden, sondern auch beim Scrollen auf der Seite oder wenn ein User die Maus auf der Seite bewegt. Ausgelagerte CSS- oder JS-Dateien können ausserdem durch Browser gecached werden und verringern so auch die Ladezeit (siehe Expiration Header). Ein nützliches Tool zur Optimierung von CSS- und JS-Dateien wird von Google zur Verfügung gestellt: minify.

Vermeidung unnötiger Anfragen durch Redirects

Umwege auf Ressourcen durch Redirects kosten Zeit und schaden der Performance. Wird beispielsweise ein Bilder-Verzeichnis auf ein anderes umgezogen, die Dateipfade der Bilder jedoch nicht angepasst, entsteht durch die Umleitung eine Verzögerung. Häufig lassen sich Weiterleitungen jedoch nicht vermeiden, z. B. bei Trackinglinks oder Werbebannern von Drittanbietern.

Aktivierung von KeepAlive

Seit der HTTP-Version 1.1 gibt es die Möglichkeit, persistente Verbindungen aufzubauen. Diese nutzen die Verbindung zwischen Client und Server mehrfach. Durch dieses Vorgehen muss die Verbindung nicht jedes Mal neu aufgebaut werden und erspart so beiden Parteien einen wiederholten Handshake.

Gemäß HTTP-Spezifikation sollten zwar nicht mehr als zwei Verbindungen gleichzeitig zum Server unterhalten werden, um diesen nicht extrem zu belasten. Doch nicht alle Browser halten sich an diese Empfehlung. So erlaubt z. B. der Internet Explorer 8 bis zu sechs gleichzeitige Verbindungen zum selben Server. Unter Apache sieht die Einstellung von KeepAlive bei Apache 2.2 beispielsweise folgendermaßen aus:

KeepAlive-Direktive:
Syntax: KeepAlive On|Off, voreingestellt auf "Off"

KeepAliveTimeout-Direktive:

Syntax: KeepAliveTimeout Sekunden, voreingestellt auf 5

 

Weitere Maßnahmen zur Optimierung durch die Erhöhung gleichzeitiger Abrufe und Minimierung der abzurufenden Dateien werden im nächsten Artikel der Reihe “Speed matters” gegeben.