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.
Messen
Bevor Sie Optimierungen vornehmen, sollten Sie immer zuerst den aktuellen Status der Anwendung analysieren.
- Klicke auf Zu bearbeitende Remixe, damit das Projekt bearbeitet werden kann.
- Um die Website als Vorschau anzusehen, wählen Sie App ansehen und dann 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:
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:
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.
- Klicken Sie auf die Schaltfläche Tools.
- Klicken Sie auf die Schaltfläche Console.
- 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
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 AntwortheaderContent-Encoding
aufbr
gesetzt. - Der Header
Content-Type
wird aufapplication/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.
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
.