Kosten sparen mit HTTP-Kompression

25.08.2003 von THOMAS WOELFER 
Eine gut besuchte Website verursacht erhebliche Kosten für den entstehenden Datenverkehr. Wie Sie mittels HTTP-Kompression bei Apache und IIS bares Geld sparen können, zeigt dieser Beitrag.

Den größten und unkalkulierbarsten Kostenblock beim Betrieb einer Webseite macht der Traffic der jeweiligen Anbindung aus. Jedermann, der eine größere Webseite betreibt, versucht, das Datenvolumen und die Bandbreite möglichst gering zu halten: Sind die ausgelieferten Seiten klein, erscheinen sie dem Leser zum einen schneller - zum anderen bedeuten kleinere Seitengrößen auch geringere Kosten für den Traffic.

Der Umstand, dass die meisten Dateien auf einer lokalen Festplatte komprimiert werden können, ist kein Geheimnis. Natürlich gilt das aber auch für Webseiten auf der Platte des Servers. Nachdem es sich bei HTML-Dateien um reine Textdateien handelt - zudem noch um solche, in denen immer wieder identische Elemente in Form der HTML-Tags auftauchen -, eignen sich diese Dateien sogar besonders gut für eine Komprimierung. Allein auf der Festplatte des Servers bringt das nicht besonders viel, wenn die Platte nicht gerade ohnehin unterdimensioniert ist.

Aber auch die Übermittlung selbst von Webseiten kann in komprimierter Form an den Client geschehen, und das spart Bandbreite und Datenvolumen. HTML-Seiten lassen sich im Allgemeinen auf etwa ein Viertel schrumpfen, mit ein bisschen Glück sogar deutlich stärker.

Vorteil: Schneller surfen

Abgesehen von der eingesparten Bandbreite hat das Ausliefern von komprimierten Seiten einen weiteren Vorteil: Es geht nicht nur ums Geld. Komprimierte Seiten sind deutlich kleiner als ihre unkomprimierten Originale. Das bedeutet, dass weniger Daten pro Seite transportiert werden müssen. Und das wiederum heißt, dass die Seite schneller beim Client ist. Der Surfer sieht die Inhalte also viel eher und hat seinen ersten Eindruck von der Webseite deutlich früher. Denn wenn nur noch ein Viertel der Daten transportiert werden muss, ist die Seite auch vier Mal schneller im Browser geladen. Das stimmt natürlich nicht ganz, denn die anderen Elemente der Seite, zum Beispiel Bilder, müssen ja auch noch geladen werden. Allerdings: Die Bilder sind vielleicht schon beim Client - und wenn die Haltbarkeitszeiten für die Bilddaten richtig gesetzt sind, fällt die Ladezeit für die Bilder nicht weiter ins Gewicht.

Eine schneller ausgelieferte Seite freut aber nicht nur den Surfer, sondern ebenso den Site-Administrator. Denn sein Vorteil ist, dass der eigene Server mehr Surfer verkraften kann. Wird eine Seite schneller ausgeliefert, wird der zugehörige HTTP-Dämon (unter NT der zugehörige Thread) früher beendet, und die belegten Sockets werden schneller wieder frei. Das bedeutet letzten Endes je nach Zugriff, dass der Rechner auch weniger Last zu verkraften hat. Beim Ausliefern komprimierter Webseiten handelt es sich also um eine Tuning-Maßnahme für Webserver, die dem Betreiber nebenher noch Geld für die belegte Bandbreite spart.

So viel zur Theorie. Ob die Server-Last in der Praxis durch die Auslieferung komprimierter Seiten tatsächlich verringert wird, ist von einigen weiteren Faktoren abhängig. Aber selbst wenn man nur Geld für die Bandbreite spart und dem Surfer ein besseres Surfverhalten geboten wird: Das Komprimieren lohnt sich auf jeden Fall.

Damit wäre der erste Faktor angesprochen, von dem die tatsächliche Lastersparnis abhängt: Man darf nämlich nicht vergessen, das die Seiten erst einmal komprimiert werden müssen - und das erzeugt seinerseits zunächst einmal Last auf dem Rechner. Wie viel, hängt davon ab, ob einmal komprimierte Seiten zwischengespeichert werden können und nicht wieder komprimiert werden müssen. Ob das überhaupt geht, ist vom verwendeten Server beziehungsweise den verwendeten Zusatzprodukten abhängig.

Seite komprimiert ausliefern

Die Theorie ist klar: Komprimierte Webseiten sind offensichtlich ein Muss. Wie aber geschieht das? Einfach nur gzip oder WinZip anwerfen und Dateien vor dem Hochladen zum Webserver komprimieren, reicht nicht aus - zumal komprimiert ausgelieferte Seiten das eine oder andere Problem aufwerfen.

Zunächst einmal muss man wissen: Die Auslieferung von HTML-Seiten in kodierter Form stellt von Haus aus kein Problem dar. Dabei kann es sich im Prinzip um eine beliebige Kodierung handeln - die Kompression ist da nur eine Spezialform der Kodierung. Um genau zu sein, ist sogar die ganze normale "Plaintext"-Form lediglich eine Spezialform der Kodierung - nämlich die Spezialform "Ohne besondere Kodierung".

Beim Kodieren einer Webseite unterscheidet man zwischen dem "Content-Encoding" und dem "Transfer-Encoding". Bei Ersterem geht es darum, den Inhalt vor der Auslieferung zu kodieren, bei Letzterem darum, den Inhalt während der Übertragung zu kodieren. Für die Komprimierung von Webseiten hat diese Unterscheidung in der Praxis aber keine Auswirkung, da viele Webseiten ohnehin beim Abruf dynamisch erzeugt werden: Eine Unterscheidung zwischen dem Zustand vor und während der Auslieferung wird da schwierig.

Aus diesem Grund wird im Folgenden auch immer von "Transfer Encoding" gesprochen. Auch, wenn es sich in einigen der angesprochenen Fälle um "Content-Encoding" handelt.

Beim Transfer-Encoding ist es gleichgültig, ob die Kodierung nun eine Verschlüsselung, eine Komprimierung oder irgendein anderes Verfahren darstellt. Wichtig ist allerdings, dass der Client (also der Browser des Surfers) im Zuge des Request mitgeteilt hat, dass er eine bestimmte Form der Kodierung tatsächlich verarbeiten kann.

Die Komprimierungsverfahren

Für die Komprimierung gibt es ein extra standardisiertes Verfahren - eigentlich sogar zwei - die die Namen gzip beziehungsweise deflate tragen. Beide sind Teil des HTTP/1.1-Standards, und dieser Standard wird von allen gängigen Browsern unterstützt. Zumindest unterstützen alle gängigen Browser Transfer-Encoding im gzip-Format über HTTP/1.1. Wie das bei Browsern immer so ist, gibt es Probleme - zum Beispiel, dass einige ältere Browser zwar behaupten, HTTP/1.1 zu verstehen, das dann aber doch nicht können. Im Wesentlichen ist es aber so, dass praktisch alle Microsoft-Browser ab IE 4.0 und alle von Netscape ab Version 3.0 das Protokoll unterstützen. Um auch auf etwas ausgefallenere Browser einzugehen: Sogar der textbasierte Lynx-Browser kommt mit Transfer-Encoding in HTTP/1.1-Verbindungen klar.

Meldet sich ein Browser hingegen als HTTP/1.0-kompatibler Client am Server an, so muss der Server einfach nur weniger tun: Im Wesentlichen entfällt dann der Komprimierungsschritt, so dass die Seite in ihrer normalen Form ausgeliefert wird.

Wie nun genau die Komprimierung auf dem Server erfolgen soll und wie sie konfiguriert wird, hängt vom verwendeten Webserver ab. Im Folgenden finden Sie daher zwei Erklärungen: eine für den IIS 5/6 von Microsoft und eine zweite für den Apache 1.3.x.

Transfer-Encoding mit Apache

Von Haus aus beherrscht der Apache-Webserver keine Komprimierung, sie lässt sich jedoch mit einem separaten Modul nachrüsten. Dieses trägt die Bezeichnung mod_gzip.

Ein einfacher Eintrag in httpd.conf, der Konfigurationsdatei von Apache, reicht allerdings nicht aus, damit der Server Dateien komprimiert überträgt. Dazu müssen Sie schon ein bisschen mehr Hand anlegen.

Das Modul mod_gzip ist eine Open-Source-Lösung, so dass Sie auch Zugriff auf den Quellcode des Moduls haben. Wenn Sie das jedoch nicht wollen, können Sie ohne den Quellcode auskommen, denn es gibt eine fertig kompilierte Variante, die in Form eines Binary heruntergeladen werden kann. Ursprünglicher Hersteller von mod_gzip ist die Firma Hyperspace Communications, doch deren Webseite ist seit Längerem nicht mehr erreichbar. Das Modul lässt sich aber immer noch bei freshmeat herunterladen:

Im einfachsten Fall laden Sie das Binary für Ihre Plattform herunter und kopieren es in das Verzeichnis, in dem Sie auch die anderen Module untergebracht haben. Das ist in den meisten Fällen das Verzeichnis /usr/lib/apache.

Da es sich bei mod_gzip um ein ganz normales Modul für Apache handelt, müssen Sie es per Eintrag in der httpd.conf laden lassen. Dazu suchen Sie zunächst die Stelle, an der auch die anderen Module geladen werden. In einer normalen Apache-Konfigurationsdatei sollten Sie die richtige Stelle relativ einfach finden, denn der ganze Abschnitt ist nur ein paar Zeilen lang. Fügen Sie dann am Ende der bisher mit der Anweisung LoadModule geladenen Module eine neue Zeile hinzu. Diese hat bei einer Standardinstallation folgendes Aussehen:

LoadModule gzip_module /usr/lib/apache/mod_gzip.so

Apache konfigurieren

Schließlich müssen Sie das Modul noch konfigurieren, ihm also mitteilen, welche Dateien und Verzeichnisse komprimiert werden dürfen. Das erfolgt über die normalen Directory-Statements innerhalb der httpd.conf. Sie können also die Komprimierung bei Bedarf auf bestimmte Verzeichnisse einschränken.

Das Modul dient nicht nur zur Komprimierung von statischen HTML-Inhalten, sondern kann auch mit von Scripts oder PHP dynamisch erzeugten Inhalten umgehen. Das bedeutet im Wesentlichen, dass Sie im Normalfall eine Einschränkung auf bestimmte Verzeichnisse gar nicht durchführen müssen - abgesehen von der Testphase natürlich. Im Endeffekt wird es aber am besten sein, wenn einfach alle Ihre Inhalte in komprimierter Form ausgeliefert werden, ganz gleich, woher diese stammen.

Wenn Sie zum Beispiel einfach alle Inhalte Ihrer Site, die aus HTML- oder PHP-Seiten stammen, komprimieren möchten, dann können Sie die folgenden Anweisungen für die Konfiguration von mod_gzip verwenden.

<Directory "/myserver/public_html">
mod_gzip_on Yes
mod_gzip_minimum_file_size 1002
mod_gzip_maximum_file_size 0
mod_gzip_maximum_inmem_size 60000
mod_gzip_item_include mime "application/x-httpd-php"
mod_gzip_item_include mime text/*
mod_gzip_item_include mime "httpd/unix-directory"
mod_gzip_dechunk Yes
mod_gzip_keep_workfiles No
mod_gzip_item_include file "\\.php$"
mod_gzip_item_include file "\\.html$"
mod_gzip_item_include file "\\.htm$"
mod_gzip_item_exclude file "\\.css$"
mod_gzip_item_exclude file "\\.js$"
</Directory>

Um die Änderungen an der httpd.conf zu aktivieren, müssen Sie Apache neu starten. Danach wird Apache via mod_gzip alle angeforderten PHP- und HTML-Dateien vor der Auslieferung komprimieren. Wenn Sie den von Perl oder anderen Sprachen erzeugten HTML-Code komprimieren wollen, müssen Sie nur die Liste der item_include Dateierweiterungen entsprechend anpassen.

Eine ausführliche Erläuterung der einzelnen mod_gzip-Parameter finden Sie in der Dokumentation zu mod_gzip - das heißt, im Quellcode des Moduls.

Logfile-Format anpassen

Ob das Modul tatsächlich funktioniert und wie sich die Komprimierung auf den Datenverkehr auswirkt, können Sie verhältnismäßig einfach testen, indem Sie mod_gzip-Informationen in das HTTP-Logfile schreiben lassen. Dazu müssen Sie aber eine weitere Änderung an der Konfigurationsdatei vornehmen.

Im Wesentlichen ist dazu der Eintrag LogFormat in der httpd.conf zu verändern. Normalerweise sieht die Formatdefinition des "common" Logfile-Formats in etwa wie folgt aus:

LogFormat "%h %l %u %t \\"%r\\" %>s %b" common

Mit diesem Format erhalten Sie alle wirklich relevanten Daten im HTTP-Logfile. Um diese um die Informationen von mod_gzip zu erweitern, müssen Sie die Definition des "common"-Formats folgendermaßen verändern. Am besten indem Sie eine Kopie der ursprünglichen Definition bearbeiten:

LogFormat "%h %l %u %t \\"%r\\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_gzip

Dadurch definieren Sie eine neue Formatangabe, die Sie unter der Bezeichnung mod_gzip verwenden können. Zusätzlich zu den bisherigen Informationen enthält das Logfile dann noch eine Information von mod_gzip, und zwar die Komprimierungsrate der abgerufenen Datei.

Allerdings reicht die Definition eines neuen Formats allein nicht aus. Sie müssen Apache auch noch mitteilen, dass er diese Formatdefinition benutzen soll. Das erfolgt über den Eintrag CustomLog in der Konfigurationsdatei. Angenommen Sie haben das Format von oben - und zwar einschließlich des Namens - verwendet, dann muss Ihr neuer CustomLog-Eintrag wie folgt aussehen:

CustomLog PfadZuIhrerLogDateo common_gzip

Auch hier gilt wieder, dass die Änderungen erst nach einem Neustart von Apache aktiviert werden. Danach können Sie das Log mit dem Befehl

tail -f logfilename

beobachten. Das funktioniert allerdings nur unter Linux, unter Windows öffnen Sie das Logfile mit einem Texteditor. Dort sollten dann Einträge mit dem folgenden Aussehen auftauchen:

212.124.226.3 - - [18/Jul/2001:00:00:44 +0200] "GET /index_nocss.htm HTTP/1.1" 200 9521 mod_gzip: 85pct.

Wie Sie sehen, enthält die Logdatei nun Einträge, die um Angaben von mod_gzip erweitert sind. Dabei handelt es sich im Wesentlichen um einen Prozentwert, der den Komprimierungsfaktor angibt. Er beschreibt also, wie gut mod_gzip die Datei vor dem Transfer komprimieren konnte. Damit ist die Konfiguration abgeschlossen, allerdings sollten Sie nach der Installation von mod_gzip hin und wieder ein Auge auf das TMP-Verzeichnis Ihres Webservers werfen. Das Modul tendiert nämlich dazu, in diesem Verzeichnis temporäre Daten abzulegen und dann zu vergessen. Auf Dauer läuft dann die Festplatte voll, und das System wird instabil.

HTML komprimieren mit dem IIS

Beim IIS ab Version 5.0 können Sie das Transfer-Encoding deutlich einfacher einschalten. Hier müssen Sie nur ein paar Optionen aktivieren, und schon werden die Seiten komprimiert ausgeliefert. Allerdings hat man sich bei Microsoft reichlich Mühe gegeben, dieses Feature zu verstecken. Man findet die benötigten Optionen nämlich nicht ohne Weiteres. Das liegt daran, dass man diese Optionen nur Server-weit einstellen kann, und nicht dort, wo man sie normalerweise suchen würde, bei den Eigenschaften der virtuellen Verzeichnisse. Stattdessen erfolgt die Konfiguration über die allgemeinen Eigenschaften des Webservers. Des Weiteren steht dieses Feature nur bei den "echten" IIS-Varianten zur Verfügung. Die abgespeckten Versionen, wie sie zum Beispiel bei der XP Workstation vorliegen, bieten diese Möglichkeit nicht.

Folgende Schritte müssen bei IIS 5.x ausgeführt werden, um die Komprimierung zu aktivieren:

Kompression bei IIS 6

Beim IIS 6 finden Sie die Optionen zum Einschalten der Kompression in den Eigenschaften des Ordners WebSites in der Management-Konsole von IIS. In der zugehörigen Dialogbox öffnen Sie den Reiter Service (Dienst) - dort können Sie die Komprimierung einschalten.

Für die "statischen" Dateien können Sie ein paar zusätzliche Parameter angeben. Dabei handelt es sich im Wesentlichen um einen Pfad zu einem Verzeichnis für die zwischengelagerten Dateien sowie die maximale Größe dafür. Der IIS legt dann einmal komprimierte Versionen von statischen Dateien in diesem Verzeichnis ab. Ändert sich die Originaldatei, so sorgt der IIS selbstständig dafür, dass die komprimierte Variante ebenfalls erneuert wird. Dabei ist es wichtig zu beachten, dass es ein lokales Verzeichnis ist und dass es sich auf einer NTFS-Partition befindet.

Der IIS hat noch eine ganze Reihe an weiteren Parametern, mit denen sich die Kompression von Dateien beeinflussen lässt. So ist es zum Beispiel möglich, eine maximale Dateigröße anzugeben - ist eine Datei größer, wird sie nicht komprimiert. Ebenso kann man eine minimale Dateigröße angeben. Diese und weitere Optionen stehen zwar zur Verfügung - aber nicht über die normale Benutzerschnittstelle. Stattdessen müssen diese Werte in der Metabase eingetragen werden. Eine ausführliche Erläuterung dazu finden Sie in der Metabase-Dokumentation, die zum Beispiel im IIS Resource Kit verfügbar ist.

Das Einschalten der Kompression beim IIS hat allerdings eine unangenehme Nebenwirkung: Alle Dokumente werden mit einem "Haltbarkeitsdatum" ausgeliefert, das bereits abgelaufen ist, und zwar mit dem 1. Januar 1997. Das hat aber einen mehr oder minder guten Grund - es vermeidet Probleme mit Proxies. Allerdings ist dadurch das Cachen von Inhalten nicht mehr möglich, denn kein Client behält eine solche Seite im Cache.

Probleme mit komprimierten Webseiten

So schön komprimierte Webseiten sind, so unangenehm ist der auftretende Seiteneffekt. Dieser betrifft Proxy-Server, die Seiten zwischenspeichern. Einige Proxy-Server haben Probleme mit komprimierten Seiten. Der Proxy nimmt die Seite an und speichert sie in der komprimierten Form ab. Wird die Seite dann allerdings von einem Client angefordert, der keine Komprimierung versteht, so liefert der Proxy dennoch die komprimierte Version aus, anstatt sie für den Client zu entpacken oder eine unkomprimierte Version der Seite vom Server anzufordern. Das Resultat besteht darin, dass der Benutzer nur kryptische Zeichen zu sehen bekommt und frustriert auf eine andere Webseite wechselt.

Zum Glück tritt dieses Problem aber in immer weniger Fällen auf - hauptsächlich gibt es bei einigen Versionen des Internet Explorer Schwierigkeiten: Dort muss der User zwei Optionen einschalten, um komprimierte Seiten richtig sehen zu können, die über einen Proxy ausgeliefert werden. Das wäre weiter nicht schlimm, wenn nicht eine dieser Optionen per Default ausgeschaltet wäre. Es handelt sich um die Optionen "HTTP 1.1 verwenden" und "HTTP 1.1 über Proxy verwenden". Generell können Sie davon ausgehen, dass die Auslieferung von komprimierten Webseiten nur Vorteile bringt und keine relevanten Probleme in sich birgt: Zumindest dann, wenn Sie nicht selbst einen Reverse-Caching Proxy einsetzen, um Ihren Webserver zu entlasten. Zu diesem Thema wird es noch einen Beitrag geben.

Fazit

Mit komprimierten HTML-Seiten sparen Sie nicht nur eine ganze Menge Geld, sondern bieten dem Surfer auch eine "schnellere" Website an. Und das ist wichtig, denn viele Surfer geben schnell entnervt auf, wenn das Laden der Seiten zu lange dauert.

Das können Sie natürlich noch verbessern, indem Sie die ursprünglichen HTML-Seiten kompakter gestalten, denn diese sind meist viel größer, als sie es für denselben Zweck sein müssten. Das gilt besonders dann, wenn Sie HTML-Editoren verwenden, die eine Menge unnützen Code in die HTML-Dokumente einbringen. Kleinere Bilder und das Entfernen nicht verwendeter Stylesheets hilft zusätzlich bei der Reduzierung des zu übertragenden Datenvolumens. (mha)