Netzwerknutzlasten mit Brotli reduzieren und komprimieren

Michael DiBlasio
Michael DiBlasio

Dieses Codelab ist eine Erweiterung des Codelab zum Komprimieren und Komprimieren von Netzwerknutzlasten. Es wird davon ausgegangen, dass Sie mit den Grundlagen der Komprimierung vertraut sind. Im Vergleich zu anderen Komprimierungsalgorithmen wie gzip wird in diesem Codelab untersucht, wie sich mit der Brotli-Komprimierung die Komprimierungsverhältnisse und die Gesamtgröße der App weiter reduzieren lassen.

App – Screenshot

Messen

Bevor Sie Optimierungen hinzufügen, sollten Sie immer zuerst den aktuellen Status der Anwendung analysieren.

  1. Klicke auf Zum Bearbeiten Remix, damit das Projekt bearbeitet werden kann.
  2. Wenn Sie sich eine Vorschau der Website ansehen möchten, klicken Sie auf App ansehen und dann auf Vollbild Vollbild.

Im vorherigen Codelab zum Reduzieren und Komprimieren von Netzwerknutzlasten haben wir die Größe von main.js von 225 KB auf 61,6 KB reduziert. In diesem Codelab erfahren Sie, wie Sie mit der Brotli-Komprimierung die Bundle-Größe noch weiter reduzieren können.

Brotli-Komprimierung

Brotli ist ein neuerer Komprimierungsalgorithmus, der noch bessere Textkomprimierungsergebnisse als gzip liefern kann. Laut CertSimple ist die Leistung von Brotli:

  • 14% kleiner als gzip bei JavaScript
  • 21% kleiner als gzip bei HTML
  • 17% kleiner als gzip für Preisvergleichsportale

Damit Sie Brotli verwenden können, muss Ihr Server HTTPS unterstützen. Brotli wird in den aktuellen Versionen der meisten Browser unterstützt. Browser, die Brotli unterstützen, enthalten br in Accept-Encoding-Headern:

Accept-Encoding: gzip, deflate, br

Sie können den verwendeten Komprimierungsalgorithmus auf dem Tab „Netzwerk“ der Chrome-Entwicklertools im Feld Content-Encoding festlegen (Command+Option+I oder Ctrl+Alt+I):

Netzwerkbereich

Brotli aktivieren

Dynamische Komprimierung

Bei der dynamischen Komprimierung werden Assets sofort komprimiert, wenn sie vom Browser angefordert werden.

Vorteile

  • Das Erstellen und Aktualisieren von gespeicherten komprimierten Versionen von Assets ist nicht erforderlich.
  • Die Komprimierung im laufenden Betrieb funktioniert besonders gut bei dynamisch generierten Webseiten.

Nachteile

  • Das Komprimieren von Dateien auf höheren Ebenen für bessere Komprimierungsverhältnisse dauert länger. Dies kann zu Leistungseinbußen führen, da der Nutzer auf die Komprimierung der Assets wartet, bevor sie vom Server gesendet werden.

Dynamische Komprimierung mit Node/Express

Die Datei server.js ist für die Einrichtung des Knotenservers verantwortlich, auf dem die Anwendung gehostet wird.

var express = require('express');

var app = express();

app.use(express.static('public'));

var listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

Aktuell importieren Sie lediglich express und verwenden die Middleware express.static, um alle statischen HTML-, JS- und CSS-Dateien in public/directory zu laden. Diese Dateien werden mit jedem Build von Webpack erstellt.

Damit alle Assets bei jeder Anfrage mit Brotli komprimiert werden, kann das Modul shrink-ray verwendet werden. Fügen Sie es zuerst als devDependency in package.json hinzu:

"devDependencies": {
  //...
  "shrink-ray": "^0.1.3"
},

Importieren Sie es in die Serverdatei server.js:

var express = require('express');
var shrinkRay = require('shrink-ray');

Fügen Sie sie als Middleware hinzu, bevor express.static bereitgestellt wird:

//...
var app = express();

// compress all requests
app.use(shrinkRay());

app.use(express.static('public'));

Aktualisieren Sie nun die App und sehen Sie sich im Steuerfeld „Netzwerk“ die Bundle-Größe an:

Paketgröße mit dynamischer Brotli-Komprimierung

Sie sehen jetzt im Content-Encoding-Header, dass brotli aus bz angewendet wird. main.bundle.js wurde von 225 KB auf 53,1 KB reduziert! Dieser Wert ist im Vergleich zu gzip (61,6 KB) etwa 14% kleiner.

Statische Komprimierung

Der Grundgedanke hinter der statischen Komprimierung besteht darin, die Assets vorab zu komprimieren und zu speichern.

Vorteile

  • Die Latenz aufgrund der hohen Komprimierungsstufen spielt keine Rolle mehr. Dateien müssen nicht spontan komprimiert werden, da sie jetzt direkt abgerufen werden können.

Nachteile

  • Assets müssen bei jedem Build komprimiert werden. Die Build-Dauer kann sich bei einer hohen Komprimierung erheblich verlängern.

Statische Komprimierung mit Node/Express und Webpack

Da bei der statischen Komprimierung Dateien im Voraus komprimiert werden, können die Webpack-Einstellungen im Rahmen des Build-Schritts so geändert werden, dass Assets komprimiert werden. Hierfür kann brotli-webpack-plugin verwendet werden.

Fügen Sie es zuerst als devDependency in package.json hinzu:

"devDependencies": {
  //...
 "brotli-webpack-plugin": "^1.1.0"
},

Importieren Sie es wie jedes andere Webpack-Plug-in in die Konfigurationsdatei webpack.config.js:

var path = require("path");

//...
var BrotliPlugin = require('brotli-webpack-plugin');

Fügen Sie es in das Plug-in-Array ein:

module.exports = {
  // ...
  plugins: [
    // ...
    new BrotliPlugin({
      asset: '[file].br',
      test: /\.(js)$/
    })
  ]
},

Das Plug-in-Array verwendet die folgenden Argumente:

  • asset: Der Name des Ziel-Assets.
  • [file] wird durch den Dateinamen des ursprünglichen Assets ersetzt.
  • test: Alle Assets, die diesem Regex entsprechen (JavaScript-Assets mit der Endung .js), werden verarbeitet.

main.js wird beispielsweise in main.js.br umbenannt.

Wenn die App neu geladen und neu erstellt wird, wird jetzt eine komprimierte Version des Haupt-Bundles erstellt. Öffne die Glitch Console, um dir den Inhalt des endgültigen public/-Verzeichnisses anzusehen, das vom Knotenserver bereitgestellt wird.

  1. Klicken Sie auf die Schaltfläche Tools.
  2. Klicken Sie auf die Schaltfläche Console.
  3. Führen Sie in der Console die folgenden Befehle aus, um zum Verzeichnis public zu wechseln und alle zugehörigen Dateien anzusehen:
cd public
ls -lh
Bundle-Größe mit statischer Brotli-Komprimierung

Die komprimierte Brotli-Version des Bundles, main.bundle.js.br, wird jetzt hier gespeichert und ist ~76% kleiner (225 KB gegenüber 53 KB) als main.bundle.js.

Weisen Sie als Nächstes den Server an, diese mit Brotli komprimierten Dateien jedes Mal zu senden, wenn ihre ursprünglichen JS-Versionen angefordert werden. Dazu können Sie in server.js eine neue Route definieren, bevor die Dateien mit express.static bereitgestellt werden.

var express = require('express');

var app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.br';
  res.set('Content-Encoding', 'br');
  res.set('Content-Type', 'application/javascript; charset=UTF-8');
  next();
});

app.use(express.static('public'));

Mit app.get wird dem Server mitgeteilt, wie er auf eine GET-Anfrage für einen bestimmten Endpunkt antworten soll. Mit einer Callback-Funktion wird dann definiert, wie diese Anfrage verarbeitet werden soll. Die Route funktioniert so:

  • Wenn Sie '*.js' als erstes Argument angeben, funktioniert dies für jeden Endpunkt, der ausgelöst wird, um eine JS-Datei abzurufen.
  • Im Callback wird .br an die URL der Anfrage angehängt und der Antwortheader Content-Encoding ist auf br gesetzt.
  • Der Header Content-Type wird auf application/javascript; charset=UTF-8 gesetzt, um den MIME-Typ anzugeben.
  • Schließlich sorgt next() dafür, dass die Sequenz zu jedem nachfolgenden Callback fortgeführt wird.

Da einige Browser die Brotli-Komprimierung möglicherweise nicht unterstützen, prüfen Sie, ob Brotli unterstützt wird, bevor Sie die mit Brotli komprimierte Datei zurückgeben. Prüfen Sie dazu den Anfrageheader Accept-Encoding, der br enthält:

var express = require('express');

var app = express();

app.get('*.js', (req, res, next) => {
  if (req.header('Accept-Encoding').includes('br')) {
    req.url = req.url + '.br';
    console.log(req.header('Accept-Encoding'));
    res.set('Content-Encoding', 'br');
    res.set('Content-Type', 'application/javascript; charset=UTF-8');
  }
  next();
});

app.use(express.static('public'));

Werfen Sie nach dem Aktualisieren der App noch einmal einen Blick auf das Steuerfeld „Netzwerk“.

Paketgröße von 53,1 KB (ab 225 KB)

Fertig! Sie haben Ihre Assets mit der Brotli-Komprimierung weiter komprimiert.

Fazit

In diesem Codelab wurde veranschaulicht, wie du mit brotli die Gesamtgröße deiner App weiter reduzieren kannst. Sofern unterstützt, ist brotli ein leistungsstärkerer Komprimierungsalgorithmus als gzip.