Content Komprimierung mit mod_deflate und Apache 2

Warum soll ich meinen Content Komprimieren?

Hierfür gibt es einige Argumente:

  1. Verringerung der nötigen Bandbreite, Verkleinerung des Volumens der Seite
  2. Ggf. schneller Ladezeiten beim Nutzer
  3. Good Style ;-)

Tatsächlich ist es so, das heute viele Webseiten auf Komprimierung Ihrer Daten setzen, dies ist mit modernen CPUs und effektiven Modulen wie mod_deflate, selbst bei hochvolumigen Seiten, kein Problem mehr. Hiermit kann ohne großen Aufwand massiv Bandbreite gespart werden, da nahezu alle modernen Browser mit komprimierten Inhalten umgehen können. Nach meinen Erfahrungen kann man locker 10 bis 20% Traffic einsparen, aber auch hier ist das ganze natürlich abhängig von den lokalen Gegebenheiten.

Hier eine Beispielkonfiguration im Apache:

#Maximize Compression
DeflateCompressionLevel 9
<Location />
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems…
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won’t work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don’t compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don’t deliver the wrong content
Header append Vary User-Agent env=!dont-vary

</Location>

Mit dem Parameter „DeflateCompressionLevel“ setzt man, wie bei gzip auch, die Stärke der Kompression. 9 ist das Maximum und 1 das schwächste. Dies kann man je nach Serverleistung variieren, wobei das ganze mit mod_deflate ziemlich effizient ist und ich auch mit einem 9 nur einen sehr geringen Anstieg der Serverlast hatte (Server mit mehreren Million Zugriffen/Tag). Der Rest der Konfiguration ist 1 zu 1 aus dem Apache Handbuch kopiert und ich hatte bisher nie Probleme damit.


Date Wed, 20 Jan 2010 08:12:01 GMT
Content-Type text/html;charset=ISO-8859-15
Vary Accept-Encoding,User-Agent
Content-Encoding gzip
Content-Length 6389
Xonnection close

Hier seht Ihr nochmal wie das dann im Header, welchen Ihr mit Firebug oder ähnlichem sehen könnt, anschließend aussieht. Content-Encoding ist gzip, das Kompressionslevel kann man hier nicht sehen, dieses wird im Header nicht angegeben. Ihr könnt allerdings mal mit dem CompressionLevel Paramter rumspielen und euch dann die Content-Length anschauen.

Hier noch der Link zum Apache Manual

Expire Header mit mod_expire im Apache 2

Wozu Expire Header?

Oft kommt es vor, das man Daten über einen Webserver ausliefert, welche lange Zeit konsistent bleiben, Logos, bestimmte Grafiken etc. Wenn man solche Bestandteile auf seiner Webseite hat, sollte man diese mit einem Expire Header versehen. Der Expire Header bewirkt dabei, das die statischen Bestandteile der Seite bei (den meisten) Nutzern nur einmal heruntergeladen werden und bis zum Ende der Expiration im Cache des Browser gehalten werden. Besucht der Anwender innerhalb der Expiration Zeit die Webseite nochmals, werden die statischen Bestandteile aus dem lokalem Cache des Benutzers geladen und müssen somit nicht erneut heruntergeladen werden. Dies bietet zwei Vorteile, zum einen spart man damit Bandbreite und Datenvolumen zum anderen ist die Ausgabe aus dem Cache, des Browsers, in der Regel deutlich schneller als das Herunterladen des Contents. Bei der Verbreitung von Breitbandanschlüßen (zu mindestens in Europa) kommt dem Argument des schnelleren Seitenaufbaus oft mehr Bedeutung zu als der genutzten Bandbreite, wobei dies natürlich auch stark vom jeweiligen Angebot abhängt.

Hin und wieder hat man den Bedarf Expire Header von bestimmten Dateitypen zu setzen, entweder weil die dahinterliegende Applikation dies nicht richtig kann, oder weil statischer Content direkt über den Apache ausgeliefert werden soll. Hierzu kann man das Modul mod_expire des Apache’s verwenden.

Hier ein Beispiel:

#set expire header for the static directorys to 7 days
<Directory /img/>
ExpiresActive On
ExpiresDefault „access plus 7 days“
</Directory>

In diesem Beispiel wird ein Expire Header für von 7 Tagen (bei wirklich statischem Content zu kurz) auf das Verzeichnis /img gesetzt.

Sobald das Modul aktiv ist und erfolgreich Arbeitet, kann man sich z.B. mit Firebug anschauen ob die Änderungen erfolgreich waren:
Date Wed, 20 Jan 2010 07:22:58 GMT
Server Apache
Last-Modified Wed, 08 Oct 2008 08:36:30 GMT
Etag "eb039a-33-458b9d013df80"
Accept-Ranges bytes
Content-Length 51
Cache-Control max-age=604800
Expires Wed, 27 Jan 2010 07:22:58 GMT
Content-Type image/gif

Hier sieht man nun sehr schön wie im Header die entsprechenden Expire Informationen gesetzt werden.

Hierzu gehören sowohl das Feld „Last-Modified“, „Cache-Control“ und natürlich „Expires“.