Die Anfrage eines Clients (z.B. eines Browsers) an einen Webserver nennt sich HTTP Request. Eine Anfrage wird immer dann gestellt, wenn eine Datei oder ein Script geladen werden soll, dessen Inhalt sich noch nicht im Browser-Cache befindet. Die Antwort des Servers und der zugehörige Datenstrom hingegen ist der Response.
Jeder Request muss dabei komplett aufgelöst werden. So wird je Anfrage ein DNS Lookup gestellt, um die Webadresse aufzulösen, die Pakete müssen über verschiedene DNS Server geroutet werden, um an ihr Ziel zu gelangen (vgl. mit traceroute / tracert) und am Ende steht der Webserver, der je nach Konfiguration, aktuellem Besucheransturm und Leistung der Hardware ebenfalls eine gewisse Latenzzeit besitzt, bis die eingehende Anfrage bearbeitet wird.
Hinzu kommt, dass die Anzahl parallel abzuarbeitender Requests insbesondere bei älteren Browsern sehr gering ist. Um die Folge-Anfragen abzusenden, warten diese darauf, dass die vorherigen Requests komplett beantwortet wurden.
Die Performance Messung von WebPagetest ist eine tolle Möglichkeit, um die Geschwindigkeit einer Website sowie die Anzahl der Requests zu ermitteln. Dabei unterscheidet das Online-Tool zwischen Erstaufruf (First View) und dem wiederholtem Aufruf (Repeat View), bei dem Browser-Caching-Mechanismen greifen (sofern diese vom Webmaster entsprechend für die jeweilige Website eingerichtet wurden).
Beim obigen Test wurden als Test-Standort Frankfurt, DE und als Browser der IE 7 eingetragen. Die jeweiligen Requests sind sehr schön als Waterfall - inkl. der jeweiligen Transfer- und Verbindungsdauer aufgelistet. Wer es nutzt kann diese Informationen auch direkt im Browser über das Addon <link http: getfirebug.com external-link-new-window>Firebug auflisten lassen. Auf Seitenreport sieht man an obiger Grafik sehr gut, dass die CSS Sprites mal wieder überarbeitet werden sollten, da in den letzten Monaten viele kleine Grafiken hinzugekommen sind.
Alle gängigen Browser können nur eine bestimmte Anzahl an Requests parallel verarbeiten. Je geringer die Anzahl parallel downloadbarer Requests und je höher die Request-Anzahl, desto langsamer wird der Seitenaufbau beim Benutzer, da die neuen Requests erst dann angefordert werden, wenn die alten abgearbeitet wurden. Die folgende Liste gibt Aufschluss darüber, welche Anzahl an Requests gängige Browser gleichzeitig anfordern:
Browser | Anzahl paralleler Requests |
Firefox 2 | 2 |
Firefox 3+ | 6 |
Opera 9.26 | 4 |
Opera 12 | 6 |
Safari 3 | 4 |
Safari 5 | 6 |
Internet Explorer 7 | 2 |
Internet Explorer 8 | 6 |
Internet Explorer 10 | 8 |
Chrome | 6 |
Es steht außer Frage, dass bei dem enormen Einfluss, den HTTP Requests auf die Website-Geschwindigkeit haben, die Anzahl der Requests so niedrig wie möglich gehalten werden sollte. Die folgenden 7 Optimierungshebel können die Anzahl der Requests vermindern und die Website dadurch schneller machen:
Oftmals werden mehrere CSS- und JavaScript auf einer Website eingebunden. Dies ist völlig normal, da eine logische Entwicklungs-Struktur darauf aufgebaut ist, dass verschiedene logische Abschnitte auch in verschiedene Dateien ausgelagert werden. So kann eine Website beispielsweise die jquery-min.js und zusätzlich einige JS-Dateien verschiedener jQuery Addons laden. Oder eine layout.css plus mehrere Mini-Stile in Form von table.css etc. Diese Handhabung ist sinnvoll und erspart viel Arbeit bei der Pflege umfangreicherer Web-Projekte und sorgt dafür, dass viele Stile in anderen Projekten wiederverwendet werden können.
Allerdings bedeutet auch jedes Laden einer CSS oder JavaScript Datei einen zusätzlichen (zeitfressenden) HTTP Request. Sinnvoll ist es daher, die verschiedenen CSS Dateien automatisiert zusammenzuführen, um die Website Performance zu erhöhen ("merge"). Für TYPO3 übernimmt dies z.B. die Extension scriptmerger.
Oftmals werden CSS- und JavaScript-Dateien sowie Bilder bei jedem Aufruf einer Website oder sogar beim Laden einer neuen Unterseite komplett neu geladen. Dies ist vor allem deshalb nicht sinnvoll, weil sich CSS Angaben bei einem fertigen Webdesign meistens nur noch in langfristigeren Zeitabschnitten ändern (z.B. wöchentlich). Jedes Laden einer Datei, die eigentlich aus dem Cache geholt werden könnte, erhöht den Traffic (und damit die Webhosting-Kosten) sowie die Ladezeit beim Endbenutzer (und führt damit als direkte SEO-Auswirkung zu schlechteren Platzierungen in den Suchmaschinen).
Die Caching-Dauer sollte daher für alle cachebaren Inhalte auf einen sinnvollen Wert nicht unter 1 Woche gesetzt werden.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 second"
ExpiresByType text/html "access plus 1 second"
ExpiresByType image/gif "access plus 15 days"
ExpiresByType image/png "access plus 15 days"
ExpiresByType image/jpg "access plus 15 days"
ExpiresByType image/jpeg "access plus 15 days"
ExpiresByType text/css "access plus 15 days"
ExpiresByType image/x-icon "access plus 15 days"
ExpiresByType text/javascript "access plus 15 days"
ExpiresByType application/x-javascript "access plus 15 days"
ExpiresByType application/javascript "access plus 15 days"
ExpiresByType application/x-shockwave-flash "access plus 15 days"
ExpiresByType application/xhtml+xml "access plus 1 second"
</IfModule>
Insbesondere bei älteren Websites finden sich diverse Layoutgrafiken, die problemlos durch CSS (Platzhalter-Grafiken) oder CSS3 (z.B. Buttons oder Box-Schatten) ersetzt werden können. Dadurch können oftmals eine Vielzahl Requests eingespart werden. Für Platzhalter Grafiken eignen sich dabei DIV-Container mit festen Höhen und Breiten und für Buttons CSS3 Stile wie background-gradient, border-radius, text-shadow usw..
In Anlehnung an Computerspiele, in denen Figuren und deren unterschiedlichen Bewegungen meist zusammengefasst in einem Bild (Sprite) abgespeichert wurden, beschreiben CSS Sprites synonym eine Technik, in der ein Bild alle auf einer Website zu verwendeten Grafiken beinhaltet. Die Verwendung von CSS Sprites kann die Anzahl von HTTP Requests deutlich reduzieren, da statt vieler einzelner Bilder nunmehr nur noch ein einziges Bild geladen werden muss. Dieses Bild wird per Background-Position-Angaben dann so positioniert, dass jeweils der Bildausschnitt angezeigt wird, der die jeweilige Grafik enthält. CSS Sprites sind vor allem für kleinere Grafiken sinnvoll. Zur leichten Erstellung von CSS Sprites eignen sich u.a. die Online-Tools <link http: spritepad.wearekiss.com external-link-new-window>SpritePad und der <link http: spritegen.website-performance.org external-link-new-window>CSS Sprite Generator.
.image-first{left:0; width:46px; background: url('sprites.png') 0 0;}
.image-second{left:63px; width:43px; background: url('sprites.png') -47px 0;}
Bilder lassen sich mittels <link http: de.wikipedia.org wiki data-url external-link-new-window>Data-URI base64-codiert direkt im HTML oder CSS Quellcode einbinden. So entfällt das Laden einer zusätzlichen Ressource und die Website lädt schneller. Data-URIs eignen sich vor allem für das Einbinden kleinerer Grafiken:
ul.checklist li.complete {
margin-left: 20px;
background: url('data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAABAAAAA
QAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2
Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D
/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A
6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') top left no-repeat;
}
Zur Erstellung von Data-URIs eignen sich Online-Tools wie der <link http: dopiaza.org tools datauri index.php external-link-new-window>data: URI Generator von dopiaza.
Statt mehrerer einzelner verlinkter Grafiken ist es oftmals sinnvoller, Image Maps zu verwenden, da diese nur aus einem Bild bestehen und somit auch nur einen HTTP Request benötigen. ImageMaps können die Performance einer Website dadurch deutlich erhöhen. Die Verlinkung der einzelnen Bereiche im Bild, wahlweise mit MouseOver Text, erfolgt dabei über die Angabe entsprechender Koordinaten:
<img src="map.png" alt="my-map" usemap="#mymap" />
<map name="mymap">
<area shape="rect" coords="9,372,66,397" href="https://domain.tld" />
</map>
Auch AJAX kann helfen, die HTTP Requests deutlich zu reduzieren. Nicht immer ist es nötig, bei einer Änderung der Seite die komplette Webpage neu zu laden. Oftmals genügt es bereits, den von der Änderung betroffenen Bereich mit AJAX dynamisch zu aktualisieren, um das gewünschte Ergebnis zu erhalten. Diesen Weg geht beispielsweise Facebook auf seiner Seite "Freunde vorschlagen". Die Liste kann endlos weiter nach unten gescrollt werden, wobei sie dynamisch erweitert wird. Die gängigere Variante ist eine Liste mit Vor- und Zurück-Button sowie dem jeweils aktuellen Seitenindex. Die Facebook Variante spart enorme Requests, ist deutlich schneller und für den Benutzer deutlich angenehmer.
Da alle gängigen Browser Beschränkungen besitzen, wie viele HTTP Requests gleichzeitig parallel geladen werden, drosseln zu viele Ressourcen auf einer Website die Ladezeit deutlich. Dabei sorgt ein schnellerer Seitenaufbau nachweislich für deutlich zufriedenere Besucher und in Online-Shops sogar zu mehr Verkäufen. Im SEO-Bereich werden schnelle Websites von Google mit besseren Platzierungen belohnt. Eine Minimierung der Request-Anzahl bringt einen enormen Geschwindigkeits-Schub. Es sollte daher einer der ersten Schritte bei allen Website-Performance-Optimierungen sein.