Höhere Komprimierungseffizienz mit gemeinsam genutzten Wörterbüchern

Die Datenkomprimierung ist eine bewährte Technik zur Leistungsoptimierung, mit der die Größe zulässiger Seitenressourcen reduziert wird. Früher war es üblich, gzip auf Webservern zu verwenden, um gängige textbasierte Seitenressourcen wie HTML-, CSS- und JavaScript-Dateien zu komprimieren und an den Client zu senden, wo sie dekomprimiert werden konnten. Das führt zu kürzeren Ladezeiten von Ressourcen, ohne das beabsichtigte Verhalten der Seite zu beeinträchtigen.

Obwohl gzip bereits für sich genommen sehr effektiv ist, wurden in den letzten Jahren weitere Verbesserungen bei der Komprimierung im Web festgestellt. Der Brotli-Algorithmus wurde 2016 in Chrome eingeführt und sorgte für insgesamt bessere Komprimierungsverhältnisse für geeignete Ressourcen. Bis Ende 2017 wurde Brotli von allen modernen Browsern unterstützt und die Serverunterstützung dafür wurde ausgeweitet. Seit Kurzem bietet Chrome auch ZStandard-Komprimierung an.

Das ist aber noch nicht alles! Das Chrome-Team arbeitet daran, freigegebene Wörterbücher im Web nutzbar zu machen, die jetzt im Rahmen eines Ursprungstests sowohl für Brotli als auch für ZStandard zur Verfügung stehen. Freigegebene Wörterbücher können die Brotli- und ZStandard-Komprimierung ergänzen und deutlich höhere Komprimierungsverhältnisse für Websites liefern, die häufig aktualisierten Code versenden. In einigen Fällen können sie mindestens 90% oder bessere Komprimierungsverhältnisse liefern. In diesem Beitrag erfahren Sie, wie freigegebene Wörterbücher funktionieren und wie Sie sich für Ursprungstests registrieren, um sie für Brotli und ZStandard auf Ihrer Website zu verwenden.

Freigegebene Wörterbücher erklärt

Bei der Komprimierung werden redundante Sequenzen in einer Eingabe gefunden und anhand dieser Informationen eine viel kleinere Ausgabe erstellt, die später umgekehrt werden kann. Die Komprimierung funktioniert gut im Web, da sie die Ladezeiten von Ressourcen erheblich verkürzt. Sowohl Brotli als auch ZStandard können ihre Effektivität weiter erhöhen, indem sie ein Komprimierungswörterbuch verwenden. Dabei handelt es sich um eine Sammlung zusätzlicher Muster, die von diesen Algorithmen während der Komprimierung verwendet werden können. Die hohe Effizienz von Brotli wird zu einem gewissen Grad durch die Verwendung eines internen Wörterbuchs erreicht.

Mit Brotli und ZStandard können jedoch benutzerdefinierte, von Nutzern zusammengestellte Wörterbücher verwendet werden, die für bestimmte Ressourcen spezifische Muster enthalten. In der Praxis ist ein benutzerdefiniertes Wörterbuch eine externe Datei, die auf jede Eingabe angewendet werden kann. Wörterbücher können sehr spezifisch für den Produktionscode einer Anwendung oder auch für beliebige Inhalte sein. Die Anwendbarkeit eines bestimmten Wörterbuchs auf seine Eingabe kann einen großen Einfluss auf die Komprimierungseffizienz insgesamt haben. Wörterbücher, die dem Inhalt einer Eingabe sehr ähnlich sind, liefern Ausgaben mit höheren Komprimierungsverhältnissen als Wörterbücher mit allgemeinen oder unterschiedlichen Inhalten.

Hier ist ein Beispiel dafür, wie effektiv ein benutzerdefiniertes Komprimierungswörterbuch sein kann: Angenommen, Sie verwenden für Ihre Website das Angular-Framework und die aktuelle Version ist 1.7.9. Diese Version des Angular-Frameworks ist unkomprimiert mit etwa 172 KiB. Wenn sie mit den Standardeinstellungen von Brotli komprimiert wird, beträgt die Größe etwa 53 KiB. Dies ergibt ein Komprimierungsverhältnis von fast 70 %. Angenommen, Sie möchten später auf Angular 1.8.3 upgraden. Da diese Version von Angular ungefähr die gleiche Größe wie Version 1.7.9 hat, können Sie davon ausgehen, dass das Komprimierungsverhältnis ungefähr gleich ist wie bei der Vorgängerversion.

Hier kann sich ein benutzerdefiniertes Wörterbuch als nützlich erweisen. Dazu wird ein Prozess verwendet , der als Delta-Komprimierung bezeichnet wird. Dabei kann ein Wörterbuch einer früheren Version einer Ressource zur Komprimierung einer späteren Version verwendet werden. Wenn Sie für das vorherige Beispiel die Version 1.8.3 von Angular mit Version 1.7.9 als Wörterbuch komprimiert haben, würde die Ausgabe etwas mehr als 4 KiB betragen. Dies entspricht einer Komprimierungsrate von fast 98%. Natürlich können Komprimierungswörterbücher einen großen Einfluss auf die Ladeleistung haben, und ihre Effektivität ist in realen Anwendungen bereits realisiert.

Es ist jedoch schwierig, diesen Ablauf im Web umzusetzen. Der Fehler ist, dass Sie, wenn Sie zum Komprimieren einer Ressource ein Wörterbuch verwenden, dasselbe Wörterbuch benötigen, um es zu dekomprimieren. Dieser Ablauf wurde bereits im Web (SDCH) ausprobiert, er war jedoch schwierig zu implementieren. Dieser neueste Vorschlag für die Komprimierung mit gemeinsam genutzten Wörterbuchn behebt diese Bedenken und bietet gleichzeitig erhebliche Vorteile sowohl für statische als auch für dynamische Ressourcen.

So bewirbt Chrome die Unterstützung für freigegebene Wörterbücher

Alle Browser bieten die unterstützten Komprimierungsalgorithmen über den Accept-Encoding-Anfrageheader an. Der Inhalt des Headers ist eine durch Kommas getrennte Liste der unterstützten Codierungen:

Accept-Encoding: gzip, br, zstd

Dieser Accept-Encoding-Header gibt an, dass der Browser, der die Ressource anfordert, die Komprimierungsalgorithmen gzip, Brotli und ZStandard unterstützt. Ein Webserver, der auf die Anfrage antwortet, kann dann entscheiden, welcher Algorithmus dafür verwendet werden soll.

Wenn die Unterstützung für freigegebene Wörterbücher aktiviert ist und für eine Ressource ein relevantes Wörterbuch verfügbar ist, werden dem Accept-Encoding-Header zusätzliche Tokens hinzugefügt. Diese Tokens sind br-d für Brotli und zstd-d für Zstandard. Chrome fügt auch den Hash eines verfügbaren Wörterbuchs hinzu. Darauf wird als Nächstes eingegangen.

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

Wenn ein Webserver so konfiguriert ist, dass er dieses Token erkennt, und er das Wörterbuch erkennt, kann er auf diese Anfrage mit einer Ressource antworten, die mit dem Wörterbuch für die entsprechende Codierung komprimiert wurde. Wie dies in der Praxis erreicht wird, hängt davon ab, ob es sich um eine statische oder eine dynamische Ressource handelt.

Freigegebene Wörterbuchkomprimierung für statische Ressourcen

Eine Ressource für statische Seiten gibt immer die gleiche Antwort auf eine angeforderte URL zurück. Gängige Beispiele für komprimierbare Ressourcen für statische Seiten sind JavaScript- und CSS-Dateien. Diese Ressourcen werden in der Regel für Caching-Zwecke versioniert, manchmal mit einem Hash des Dateiinhalts im Dateinamen (z. B. styles.abcd1234.css) oder einer anderen Methode zum Fingerprinting der Ressource. Diese Ressourcentypen eignen sich hervorragend für die Delta-Komprimierung, die gemeinsam genutzte Wörterbücher bieten, da statische Ressourcen oft über einen längeren Zeitraum im Cache gespeichert werden und in der Regel mit einer gewissen Häufigkeit aktualisiert werden.

Sie können ein Wörterbuch für eine statische Ressource angeben, indem Sie den Antwortheader Use-As-Dictionary dafür festlegen. Für den Header wird eines von einigen Schlüssel/Wert-Paaren verwendet. Das einzige erforderliche ist match. Es unterstützt die URLPattern-Syntax und gibt den Ressourcenpfad an, in dem das Wörterbuch verwendet werden soll:

Use-As-Dictionary: match="/dist/styles.*.css"

Stellen Sie sich den Use-As-Dictionary-Header als einen Mechanismus vor, der für zukünftige Versionen einer Ressource gilt, die dem darin angegebenen Muster entsprechen. Angenommen, auf Ihrer Website werden alle Stile in einer einzigen CSS-Datei versendet. Nehmen wir der Einfachheit halber an, dass sich die erste Version dieser Ressource unter /dist/styles.v1.css befindet und mit einem Use-As-Dictionary-Antwortheader gesendet wird, der den match-Wert /dist/styles.*.css enthält.

Nach einiger Zeit aktualisieren Sie das Preisvergleichsportal Ihrer Website und versenden eine neue Version davon (/dist/styles.v2.css). Da der Wert match, der im Antwortheader Use-As-Dictionary aus der vorherigen Version verwendet wurde, für diese Anfrage gilt, sendet der Browser einen Available-Dictionary-Header, der einen Hash des Wörterbuchs enthält, codiert als Bytesequenz für strukturierte Felder:

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

An dieser Stelle muss der Server die Komprimierung an seiner Seite konfigurieren, um sicherzustellen, dass das übereinstimmende Wörterbuch verwendet wird. Die mit diesem Wörterbuch komprimierte Ressource wird dann gesendet und zum Entpacken des Wörterbuchs wird das im Browser-Cache des Nutzers verfügbare Wörterbuch verwendet.

Wenn Sie häufig neuen Code für Ihre Website versenden, kann die Delta-Komprimierung viel bewirken. Dieses Verfahren ist jedoch flexibel. Wenn der Browser nicht feststellt, dass ein Wörterbuch im Cache des Nutzers verfügbar ist, werden die zusätzlichen br-d- oder zstd-d-Tokens im Accept-Encoding-Header nicht angegeben. In diesem Fall wird der standardmäßige Komprimierungsablauf angewendet.

Freigegebene Wörterbuchkomprimierung für dynamische Ressourcen

Dynamische Ressourcen können auch von der gemeinsam genutzten Wörterbuchkomprimierung profitieren. Dynamische Ressourcen sind solche, die sich je nach Kontext ändern, z. B. eine Nachrichtenwebsite, deren Hauptseite häufig aktualisiert wird, um Nachrichten zu veröffentlichen. HTML-Dokumente sind oft dynamische Ressourcen. In solchen Fällen kann das Wörterbuch einen Großteil der üblichen HTML-Struktur und Vorlagencode der Website enthalten. Dies führt zu komprimierten Seiten, an die nur die eindeutigen Teile jeder Seite gesendet werden.

Aufgrund der Beschaffenheit dynamisch generierter Ressourcen muss ein Wörterbuch zur späteren Verwendung auf dem Client geladen werden. Wenn ein Wörterbuch im Voraus geladen wird, ist das Anwenden der freigegebenen Wörterbuchkomprimierung auf dynamische Ressourcen spekulativ. Die Hoffnung in solchen Fällen besteht darin, dass Ihre Website genügend Zugriffe erhält, dass die Wörterbuchkosten für eine große Anzahl von Navigationen amortisiert werden können. Wenn Sie es ausprobieren möchten, geben Sie als Erstes den Speicherort des Wörterbuchs mithilfe eines <link>-Elements im HTML-Code Ihrer Seite an:

<link rel="dictionary" href="/dictionary.dat">

Wenn Chrome auf dieses <link>-Element stößt, kann es das Wörterbuch abrufen, sobald die Seite inaktiv ist, und mit niedriger Priorität, um Bandbreitenkonflikte zu vermeiden. In der Antwort für das Wörterbuch selbst muss ein Use-As-Dictionary-Header sowie der dynamische Ressourcenpfad angegeben werden, für den er gilt:

Use-As-Dictionary: match="/product/*"

Ab hier ist der Ablauf weitgehend der gleiche wie bei statischen Ressourcen. Der Browser erkennt, dass das Wörterbuch selbst auf übereinstimmende Ressourcen angewendet wird, und hängt der Anfrage einen Available-Dictionary-Header mit einem Hash des Wörterbuchinhalts an, ähnlich wie beim zuvor erläuterten Ablauf für statische Ressourcen.

Statische Ressourcen zum Build-Zeitpunkt komprimieren

Wenn Sie mit Bundlern vertraut sind, sind Sie möglicherweise mit verschiedenen Plug-ins vertraut, die Ressourcen bei der Build-Erstellung komprimieren und anschließend bereitstellen können. Mit Apache können Sie beispielsweise Anweisungen verwenden, um diese vorkomprimierten Ressourcen zum Zeitpunkt der Anfrage bereitzustellen.

Die meisten Node.js-basierten Bundler, die Komprimierung unterstützen, verwenden die integrierte Zlib-Bibliothek von Node. Zlib unterstützt Brotli und Bundler, die es verwenden, in der Regel eine Schnittstelle, über die Optionen direkt an Zlib übergeben werden können. Zlib unterstützt dann eine wörterbuchgestützte Komprimierung. Im Folgenden finden Sie einige Bundler, die die Verwendung von Wörterbüchern unterstützen:

Beachten Sie, dass verfügbare Wörterbücher für eine bestimmte Version einer Ressource möglicherweise eine beliebige frühere Version einer Ressource verwenden. Sie müssen also die Nutzerzugriffe analysieren und entsprechend planen. Strebe ein Gleichgewicht an und schaffe Ressourcen, die der maximalen Anzahl wiederkehrender Nutzer so gut wie möglich zugutekommen. CDN-Anbieter testen derzeit die Komprimierung mit gemeinsam genutztem Wörterbuch. Es sind noch keine Implementierungen für die Öffentlichkeit verfügbar, aber wir gehen davon aus, dass sich das ändern wird.

Probier es gleich aus!

Durch die Integration der gemeinsam genutzten Wörterbuchkomprimierung in die vorhandenen Komprimierungsfunktionen des Browsers kann die Ladeleistung von Websites erheblich verbessert werden, die häufig aktualisierten Produktionscode versenden und hohe Zugriffszahlen von wiederkehrenden Besuchern erhalten. Wenn Sie das freigegebene Wörterbuch komprimieren möchten, haben Sie zwei Möglichkeiten:

  1. Wenn Sie nur selbst an der Komprimierung des freigegebenen Wörterbuchs herumspielen möchten, um ein Gefühl dafür zu bekommen, können Sie die experimentelle Funktion für die Komprimierung des Wörterbuchs auf der Seite chrome://flags aktivieren.
  2. Wenn Sie dies auf Ihrer Produktionswebsite ausprobieren und sehen möchten, wie echte Nutzer von der freigegebenen Wörterbuchkomprimierung profitieren könnten, registrieren Sie sich für den Ursprungstest, um ein Token zu erhalten, und informieren Sie sich über die Funktionsweise von Ursprungstests.

Fazit

Wir sind begeistert von diesem großen Fortschritt bei der Komprimierungstechnologie im Internet und darüber, wie viel schneller vorhandene Anwendungen, die Menschen tagtäglich nutzen, damit viel schneller werden könnten. Wir möchten dich dazu ermutigen, diese neue Funktion auszuprobieren, und vor allem deine Meinung interessiert uns. Wenn Sie einen Fehler finden, melden Sie ihn auf crbug.com. Weitere Ressourcen und Tools finden Sie unter use-as-dictionary.com. Wenn Sie sich noch ausführlicher darüber informieren möchten, wie das Ganze funktioniert, ist die Erklärung ein guter nächster Schritt.