Netzwerknutzlasten mit Brotli reduzieren und komprimieren

DiBlasio
Michael DiBlasio

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

App – Screenshot

Messen

Bevor Sie Optimierungen vornehmen, sollten Sie immer zuerst den aktuellen Status der Anwendung analysieren.

  1. Klicke auf Zu bearbeitende Remixe, damit das Projekt bearbeitet werden kann.
  2. Um die Website als Vorschau anzusehen, wählen Sie App ansehen und dann Vollbild Vollbild aus.

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 die Brotli-Komprimierung diese Bundle-Größe noch weiter reduzieren kann.

Brotli-Komprimierung

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

  • 14% kleiner als gzip (JavaScript)
  • 21% kleiner als gzip (HTML)
  • 17% kleiner als gzip (Preisvergleichsportal)

Wenn Sie Brotli verwenden möchten, muss Ihr Server HTTPS unterstützen. Brotli wird in den neuesten Versionen der meisten Browser unterstützt. Browser, die Brotli unterstützen, fügen br in Accept-Encoding-Header ein:

Accept-Encoding: gzip, deflate, br

Auf dem Tab „Network“ der Chrome-Entwicklertools (Command+Option+I oder Ctrl+Alt+I) können Sie über das Feld Content-Encoding festlegen, welcher Komprimierungsalgorithmus verwendet wird:

Netzwerkbereich

Brotli aktivieren

Dynamische Komprimierung

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

Vorteile

  • Das Erstellen und Aktualisieren gespeicherter komprimierter Versionen von Assets muss nicht ausgeführt werden.
  • Die spontane Komprimierung funktioniert besonders gut bei dynamisch generierten Webseiten.

Nachteile

  • Die Komprimierung 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 wird dazu express importiert und die Middleware express.static verwendet, um alle statischen HTML-, JS- und CSS-Dateien im public/directory zu laden. Diese Dateien werden von Webpack bei jedem Build erstellt.

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

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

Importieren Sie sie 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 die Bundle-Größe im Steuerfeld "Network" an:

Paketgröße mit dynamischer Brotli-Komprimierung

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

Statische Komprimierung

Die Idee hinter der statischen Komprimierung besteht darin, dass Assets komprimiert und im Voraus gespeichert werden.

Vorteile

  • Die Latenz aufgrund hoher Komprimierungsgrade ist kein Problem mehr. Dateien müssen nicht spontan komprimiert werden, da sie jetzt direkt abgerufen werden können.

Nachteile

  • Assets müssen mit jedem Build komprimiert werden. Die Build-Zeiten können bei hohen Komprimierungsstufen erheblich länger werden.

Statische Komprimierung mit Node/Express und Webpack

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

Fügen Sie ihn 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');

Und 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 ursprünglichen Namen der Asset-Datei ersetzt.
  • test: Alle Assets, die mit diesem regulären Ausdruck übereinstimmen (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. Öffnen Sie die Glitch-Konsole und sehen Sie sich an, was sich im endgültigen public/-Verzeichnis befindet, 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 zu sehen:
cd public
ls -lh
Bundle-Größe mit statischer Brotli-Komprimierung

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

Als Nächstes weisen Sie den Server an, diese Brotli-komprimierten Dateien immer dann zu senden, wenn ihre ursprünglichen JS-Versionen angefordert werden. Definieren Sie dazu eine neue Route in server.js, 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. Mithilfe 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 zum Abrufen einer JS-Datei ausgelöst wird.
  • Innerhalb des Callbacks ist .br an die URL der Anfrage angehängt und der Antwortheader Content-Encoding 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 bis zu jedem Callback fortgesetzt wird, der möglicherweise als Nächstes kommt.

Da einige Browser die Brotli-Komprimierung unter Umständen nicht unterstützen, prüfen Sie, ob Brotli unterstützt wird, bevor Sie die Brotli-komprimierte Datei zurückgeben. Prüfen Sie dazu, ob der Accept-Encoding-Anfrageheader 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'));

Sehen Sie sich nach dem Aktualisieren der App noch einmal den Bereich „Netzwerk“ an.

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

Fertig! Du hast die Brotli-Komprimierung verwendet, um deine Assets weiter zu komprimieren.

Fazit

In diesem Codelab wurde gezeigt, wie du mit brotli die Gesamtgröße deiner App weiter reduzieren kannst. Soweit möglich, ist brotli ein leistungsstärkerer Komprimierungsalgorithmus als gzip.