Samstag, 23. Februar 2013

Optimierung von Websites mittels .htaccess (mod_deflate & mod_expires)

Ohne die eingesetzten Content-Delivery-Systeme zu kennen: Die folgenden beiden Massnahmen eigenen sich für alle Websites, und brauchen ebenso meistens keinen Eingriff in die Serversystem Software. Die Beispiele richten sich an den Apache httpd Webserver, die Prinzipien gelten aber auch für IIS, usw. Auf den meisten Shared-Hostings sind diese beiden Massnahmen standardmässig nicht umgesetzt.

Tipp 1: Serverseitige Komprimierung (mod_deflate)

Dieser Tipp gilt vor allem dann, wenn der Server über ausreichend CPU-Leistung verfügt, und die Clients eher mit geringen Datenübertragungsraten die Site besuchen (Mobiltelefone, usw.). Nach Aktivierung der Kompression, ist die Gesamtgrösse der übertragenen Daten um einiges geringer:

Serverseitige Kompression verringert die übertragene Datenmenge markant. Eine minifizierte jQuery Library wird hier von 91 KB nochmals auf 33 KB reduziert.
Auf Apache bspw. kann mit dem mod_deflate Modul die On-the-Fly Kompression von diversen Files konfiguriert werden. Das Modul ist auf den meisten Shared-Hosts von Providern zwar vorhanden, aber nicht aktiviert. Um dies zu tun, ist folgender Eintrag in die .htaccess Datei notwendig:

<ifmodule mod_deflate.c>
AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript text/javascript
</ifmodule>

Mit der Direktive "ifmodule..." wird sichergestellt, dass die Anweisung nur dann ausgeführt wird, wenn das Modul auch installiert ist - ansonsten riskiert man einen 500er Fehlercode.

Die Einstellung greift sofort, es ist also kein Neustart des Webservices notwendig.

Tipp 2: Cache Control (mod_expires)

Dieser Tipp sollte auf jeden Fall immer angewendet werden, und ist bei den meisten Shared-Hosts von Providern zwar auch wieder vorhanden, aber nicht aktiviert. Hierbei geht es darum, dass in unserem Beispiel der Apache Webserver mit jedem gesendeten Asset eine zusätzliche Header-Zeile mitliefert. In dieser steht drin, dass der Browser das Asset bei sich lokal ablegen, und erst zu angegebenem Zeitpunkt das Asset wieder beziehen soll. Eine JPEG-Grafik, die 1MB gross ist, wird also auf der lokalen Festplatte des Users abgelegt, und danach immer von dort geholt anstatt vom Server. Folgendes Bilder illustrieren die Ladezeiten bei aus- und bei eingeschalteten Expires-Header:

Nicht eingeschaltete Expires-Header: Jede Datei wird beim Aufruf der Seite erneut  abgefragt. Der Webserver ist hier intelligent genug, einen 304-Not-Modified Header zu senden, anstatt die Datei nochmals zu schicken. Dennoch braucht der Roundtrip hierzu einige Zeit!
Eingeschaltete Expires-Header: Der Webserver wird nun gar nicht mehr angefragt, sondern die Dateien werden direkt aus dem Cache des Browsers geladen. Resultat: Keine Roundtrips und damit keine Verzögerungen!
Für die Aktivierung ist folgender Eintrag in die .htaccess Datei notwendig:

<FilesMatch "\.(js|css|png|jpg)$">
  <IfModule mod_expires.c>
    ExpiresActive on
    ExpiresDefault "access plus 7 days"
  </IfModule>
  FileETag MTime Size
</FilesMatch>

Damit werden alle *.js, *.css, *.png und *.jpg Dateien beim Senden an den Client, mit dem Header versehen. Dieser besagt, dass die Dateien 7 Tage gültig sind (und sich in dieser Zeit auch nicht ändern). Würde ein User aber den "Reload"-Button im Browser betätigen, würden alle Assets neu gedownloadet - unabhängig vom Expires-Header. Man ist also bei einer fertig entwickelten Webpage damit auf der sicheren Seite.

Fazit

Die beiden Optimierungen erfordern keinen grossen Aufwand, und setzen keinen Eingriff in die Content-Management/Delivery Software voraus. In den meisten Fällen lassen sich mit diesen Anpassungen mindestens gegen 200-300ms rausholen. Bei einer Page-Load-Time von 1 Sekunde, ist dies ein Zuwachs der Geschwindigkeit von 30% - die für den User auf jeden Fall spürbar ist.