Webseiten und Kompression

| Lesezeit: ~9 Minuten

Beruflich habe ich immer wieder damit zu tun, dass ich Webseiten erstellen und warten muss. Meistens handelt es sich dabei nur um simple Landing-Pages oder einfachere Projektseiten mit vorwiegend statischem Inhalt. In dem Zusammenhang habe ich mir mal Jekyll als Static-Page-Generator angeschaut und gerade hier bietet sich ja die Kompression der Webseite an. Doch welcher Weg ist hier der beste Weg?

Ein, zwei Google-Suchen später, war ich auch schon bei diversen Research-Papern zu Kompressionsalgorithmen gelandet. Hier werden dann gerne die unterschiedlichsten Algorithmen verglichen, vor allem im Bezug darauf, welche Kompression erreicht wird und dies im Verhältnis zur benötigten Zeit. In vielen Bereichen findet man dann solche Aussagen wie "dies sollte um X beschleunigen" oder "die Ladezeit sollte dadurch um Y % verringert werden". Aber irgendwie konnte ich nichts finden, wo es mal wirklich jemand getestet hat.

Also nahm ich dies als Anlass einfach mal selbst in der Richtung tätig zu werden. Durch meine vorherige Recherche wusste ich bereits, dass ich meine Tests auf eigentlich 3 Kompressionsalgorithmen einschränken kann: Gzip, Zopfli und Brotli. Gzip ist das klassische Pferd im Stall. Ein bisschen älter, aber nach wie vor sehr gut in dem was es tut. Zopfli treibt den auch in Gzip verwendeten Deflate-Algorithmus auf die Spitze und Brotli ist relativ neu auf dem Markt und geht einen ganz anderen Weg für die Kompression. Was die einzelnen Algorithmen selbst angeht, will ich aber gar nicht zu sehr ins Detail gehen. Wichtig ist nur, dass alle modernen Browser diese Algorithmen unterstützen und dies ist der Fall.

Testaufbau

Für meine Tests habe ich einen vServer mit Ubuntu 20.04.1 LTS und dem aus den Paketquellen stammenden Webserver nginx in der Version 1.18.0 genommen. Was die Einstellungen angeht, habe ich nginx komplett bei den Standardeinstellungen belassen und nur das Modul für Brotli selber kompiliert und hinzugefügt, da dieses normalerweise nicht vorhanden ist.

nginx.conf:

load_module "modules/ngx_http_brotli_filter_module.so";
load_module "modules/ngx_http_brotli_static_module.so";

Den vHost selber habe ich auch nicht sonderlich konfiguriert. Da für Brotli allerdings eine SSL-Verbindung bestehen muss, habe ich den Server mit einem Zertifikat bestückt.

default.conf:

server {
    listen 443 ssl http2;
    root /var/www;
    index index.html index.htm index.nginx-debian.html;
    server_name _;
    location / {
        try_files $uri $uri/ =404;
    }

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    gzip off;
    gzip_comp_level 9;
    gzip_static off;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml text/javascript application/javascript;

    brotli off;
    brotli_comp_level 9;
    brotli_static off;
    brotli_types text/plain text/css application/x-javascript text/xml application/xml text/javascript application/javascript;
}

Was die Kompression selbst angeht, gibt es hier drei Möglichkeiten:

  1. Keine Kompression
  2. Die Kompression erfolgt bei Aufruf durch den Webserver (nginx)
  3. Die komprimierten Dateien liegen bereits vor und werden vom Webserver ausgeliefert (statisch)

Für meine Tests habe ich dann immer die Einstellungen für den vHost verändert um folgende Testfälle zu haben:

  • Keine Kompression
  • Gzip Stufe 6 durch nginx
  • Gzip Stufe 9 durch nginx
  • Gzip Stufe 9 statisch
  • Zopfli statisch
  • Brotli Stufe 6 durch nginx
  • Brotli Stufe 9 durch nginx
  • Brotli Stufe 9 statisch
  • Brotli Stufe 11 statisch

Die Kompression mit Zopfli erfolgt nur statisch, da es kein Modul für nginx gibt, um die Kompression zur Laufzeit durchzuführen. Dies liegt auch daran, dass die Kompressionsgeschwindigkeit von Zopfli hierfür deutlich zu langsam ist.

Boostrap starter template

Als "Webseite" für meine Tests habe ich das Bootstrap starter template mit Bootstrap v5.0.0-beta1 genommen. So verbreitet wie Bootstrap ist, bot es sich gut als Grundlage für solche Tests an. Außerdem ist da direkt alles drin, was man für so einen Test braucht: HTML, CSS und Javascript. Bei jedem Test habe ich die Seite mehrfach neu geladen und einen Mittelwert aus der Ladezeit gebildet.

Ergebnisse

Seitengröße (in kB) Ladezeit (in ms)
Ohne Kompression 237 232.5
Gzip 6 nginx 46.8 204.9
Gzip 9 nginx 46.5 209.3
Gzip 9 statisch 46.3 198.9
Zopfli statisch 43.5 200.1
Brotli 6 nginx 42.2 193.1
Brotli 9 nginx 41.6 185.2
Brotli 9 statisch 41.6 179.6
Brotli 11 statisch 37.2 207.5

Wenig überraschend ist Kompression schon durchaus von Vorteil, wenn man eine Webseite möglichst schnell an die Besucher ausliefern möchte. Eine mit Brotli auf Stufe 9 komprimierte Webseite ist immerhin nicht ganz 23% schneller beim Besucher, als wenn ich die Seite komplett ohne Kompression ausliefere. Allerdings kann man Brotli nun auch nicht per se in allen Situationen einsetzen.

Meiner Ansicht nach ergeben sich folgende Anwendungsfälle:

  • Eine komplett statische Webseite (z. B. selbstgeschriebenes HTML oder von Jekyll erzeugt)
  • Eine Webseite mit dynamischen Elementen (diverse CMS wie WordPress oder Grav)

statische Webseite

Hier bietet es sich an bereits alle Elemente der Seite vor dem Upload zu komprimieren. Zu jeder Datei gibt es dann entsprechend eine passende Datei im komprimierten Format:

index.html
index.html.gz
index.html.br

Der Webserver muss sich um nichts mehr kümmern und was der jeweilige Besucher serviert bekommt, hängt ganz davon ab, was sein Browser unterstützt. Bei aktuellen Browsern sollte dies dann aber die mit Brotli komprimierte Datei sein. Damit aber auch tatsächlich Brotli beim Besucher ankommt, muss natürlich auch der Webserver passend konfiguriert sein. Brotli gehört leider noch nicht zum Standard bei Webservern und muss zum Beispiel bei nginx extra kompiliert werden.

dynamische Webseite

In diesem Fall sollte man sich die größten, statischen Dateien vornehmen und auf jeden Fall diese auch in einer komprimierten Fassung vorliegen haben. Bei vielen Webseiten ist es schon vom Vorteil, wenn jquery auch in Brotli komprimiert vorliegt. Für alle anderen Elemente ist es gut, wenn der Webserver die Kompression übernimmt. Für mich hat sich hier Gzip mit Kompressionsstufe 6 bewährt. Dies ist der beste Kompromiss zwischen Dateigröße und Kompressionszeit.

Gzip vs. Zopfli

Gzip mit der Kompressionsstufe 9 und Zopfli sind sich beide sehr ähnlich. Wenn es darum geht das absolut kleinste Ergebnis zu erzeugen, gewinnt Zopfli. Dafür lässt es sich aber definitiv nur auf statische Dateien anwenden und ist, was die Kompressionszeit angeht, auch recht langsam. Daher wird Zoplfi nicht "on-the-fly" als Kompression bei Webservern eingesetzt. Gzip erzeugt zwar etwas größere Dateien, kann diese aber dafür schneller erzeugen und wird in der Kompressionsstufe 9 auch minimal schneller entpackt als Zopfli. Meiner Meinung nach kann man aber bei der heutigen Geschwindigkeit von PCs die Zeit zum Entpacken beim Endnutzer vernachlässigen. Somit ist es mir in dem Fall wichtiger, eine möglichst kleine Datei zu haben, die dem entsprechend auch schneller beim Webseitenbesucher ankommt. Daher sehe ich hier Zopfli für diesen Fall als die bessere Gzip-Alternative an. Durch die geringe Webseitengröße in meinem Test, sieht Zopfli hier schlechter (und langsamer) aus, als es eigentlich ist. Hier muss man einfach für sich selbst abwägen, welche Kompressionsmethode für einen die passende ist.

Brotli

Wenn man reinweg nur auf die Dateigröße und Geschwindigkeit achtet, ist Brotli die beste Wahl. Sowohl, wenn der Webserver sich selbst um die Kompression kümmert, als auch wenn die Dateien statisch vorliegen, liegt Brotli ganz klar vorn. Die Kompressionsstufe 9 scheint hier der beste Mittelweg zwischen Kompression und Geschwindigkeit zu sein. Stufe 11 führt zwar zu den kleinsten Dateien und ist damit auch am schnellsten beim Webseitenbesucher, braucht dafür aber im Vergleich deutlich länger zum Entpacken. Während der Unterschied beim Entpacken von Zopfli und Gzip nur marginal ist, ist Brotli auf Stufe 11 deutlich langsamer als auf Stufe 9, sodass man hier schon einen Unterschied wahrnehmen kann.

Fazit

Die Geschwindigkeit, die man durch Kompression gewinnt, sollte man nicht unterschätzen. Auch wenn man keine Lust hat, sich selbst um die Kompression zu kümmern, um auch noch das letzte bisschen an Geschwindigkeit aus einer Webseite herauszupressen, bietet eigentlich schon ein handelsüblicher Webserver mit Gzip-Kompression einem schon genug Vorteile. Wer mehr möchte, rückt der Webseite mit Zopfli und Brotli zu Leibe. Auch wenn Brotli schon gut unterstützt wird, sollte man sich nicht darauf verlassen, dass es tatsächlich bei allen Besuchern funktioniert. Sich beide Optionen offen zu lassen ist daher durchaus vom Vorteil. Auch wenn es initial etwas mehr Arbeit bedeutet. Wenn man aber eh nicht alles von Hand macht und gerade bei statischen Webseiten solche Tools wie Jekyll nutzt, bietet es sich an, die passenden Plugins für die Kompression zu nutzen. Das automatische Erzeugen der Webseite dauert dann zwar ein paar Sekunden länger, aber ansonsten hat man keinerlei Nachteile, wenn man die Webseite auch komprimiert zur Verfügung stellt.