To ćwiczenie w Codelabs jest dodatkiem do minimalizowania i kompresowania ładunków sieciowych. Zakładamy w nim, że znasz podstawowe pojęcia związane z kompresją. W porównaniu z innymi algorytmami kompresji, takimi jak gzip
, to ćwiczenie w Codelabs pokazuje, jak kompresja Britli może jeszcze bardziej zmniejszyć współczynnik kompresji i ogólny rozmiar aplikacji.
Zmierz odległość
Przed zagłębieniem się w optymalizacje warto najpierw przeanalizować bieżący stan aplikacji.
- Aby umożliwić edytowanie projektu, kliknij Zremiksuj do edycji.
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a potem Pełny ekran .
W poprzednim ćwiczeniach z programowania: minifikowanie i kompresowanie ładunków sieciowych zmniejszyliśmy rozmiar main.js
z 225 KB do 61,6 KB. W ramach tego ćwiczenia w programie zobaczysz, jak kompresja Brotli może jeszcze bardziej zmniejszyć rozmiar pakietu.
Kompresja Brotli
Brotli to nowszy algorytm kompresji, który zapewnia jeszcze lepsze wyniki kompresji tekstu niż gzip
. Według CertSimple skuteczność Brotli:
- O 14% mniejsza niż w przypadku języka
gzip
w przypadku JavaScriptu - O 21% mniejszy niż
gzip
w przypadku HTML - O 17% mniejsza niż w przypadku usługi porównywania cen (
gzip
)
Aby można było korzystać z brotli, Twój serwer musi obsługiwać protokół HTTPS. Brotli działa w najnowszych wersjach większości przeglądarek. Przeglądarki, które obsługują Brotli, umieszczają nagłówek br
w nagłówkach Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
Używany algorytm kompresji możesz określić w polu Content-Encoding
na karcie Sieć Narzędzi dla deweloperów w Chrome (Command+Option+I
lub Ctrl+Alt+I
):
Włączanie Brotli
Kompresja dynamiczna
Kompresja dynamiczna obejmuje kompresowanie zasobów w czasie rzeczywistym, gdy przeglądarka wysyła ich żądania.
Zalety
- Nie musisz tworzyć i aktualizować zapisanych skompresowanych wersji zasobów.
- Kompresja „w czasie rzeczywistym” sprawdza się szczególnie dobrze w przypadku stron internetowych generowanych dynamicznie.
Wady
- Kompresja plików na wyższych poziomach w celu uzyskania lepszych współczynników kompresji trwa dłużej. Może to spowodować spadek wydajności, ponieważ użytkownik czeka na skompresowanie zasobów, zanim zostaną one przesłane przez serwer.
Dynamiczna kompresja z użyciem węzła/Express
Plik server.js
odpowiada za skonfigurowanie serwera węzłów, na którym jest hostowana aplikacja.
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);
});
Obecnie wystarczy zaimportować express
i użyć oprogramowania pośredniczącego express.static
, aby wczytać wszystkie statyczne pliki HTML, JS i CSS w komponencie public/directory
(pliki te są tworzone przez pakiet internetowy przy każdej kompilacji).
Aby mieć pewność, że wszystkie zasoby są skompresowane za pomocą narzędzia brotli za każdym razem, gdy o ich zażądamy, możesz użyć modułu shrink-ray
. Zacznij od dodania go jako devDependency
w package.json
:
"devDependencies": {
//...
"shrink-ray": "^0.1.3"
},
I zaimportuj go do pliku serwera server.js
:
var express = require('express');
var shrinkRay = require('shrink-ray');
I dodaj je jako oprogramowanie pośredniczące przed podłączeniem express.static
:
//...
var app = express();
// compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
Ponownie załaduj aplikację i spójrz na rozmiar pakietu w panelu Sieć:
W nagłówku Content-Encoding
możesz teraz zobaczyć, jak zastosowano brotli
z adresu bz
.
Plik main.bundle.js
został zmniejszony z 225 KB do 53,1 KB! Jest to o około 14% mniej niż w przypadku gzip
(61,6 KB).
Kompresja statyczna
Kompresja statyczna ma na celu skompresowanie i zapisanie zasobów z wyprzedzeniem.
Zalety
- Opóźnienie spowodowane wysokim poziomem kompresji nie jest już problemem. Kompresowanie plików nie musi odbywać się na bieżąco, ponieważ teraz można je pobierać bezpośrednio.
Wady
- Przy każdej kompilacji zasoby muszą być skompresowane. Czas kompilacji może się znacznie wydłużyć, jeśli stosowane są wysokie poziomy kompresji.
Kompresja statyczna z użyciem węzła/Express i pakietu webpack
Kompresja statyczna obejmuje kompresowanie plików z wyprzedzeniem, dlatego ustawienia pakietu internetowego można zmodyfikować tak, aby kompresować zasoby w ramach etapu kompilacji. Do tego celu można użyć brotli-webpack-plugin
.
Zacznij od dodania go jako devDependency
w package.json
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
Jak każdą inną wtyczkę pakietu internetowego, zaimportuj ją do pliku konfiguracji webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
Uwzględnij go w tablicy wtyczek:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
Tablica wtyczek używa tych argumentów:
asset
: nazwa zasobu docelowego.- Wartość
[file]
zostanie zastąpiona oryginalną nazwą pliku zasobu. test
: wszystkie zasoby, które pasują do tego wyrażenia regularnego (czyli zasoby JavaScript kończące się na.js
), są przetwarzane.
Na przykład nazwa main.js
zostałaby zmieniona na main.js.br
.
Gdy aplikacja załaduje się ponownie i ponownie skompiluje, tworzona jest skompresowana wersja pakietu głównego. Otwórz konsolę Glitch, aby zobaczyć, co znajduje się w końcowym katalogu public/
obsługiwanym przez serwer węzłów.
- Kliknij przycisk Narzędzia.
- Kliknij przycisk Konsola.
- W konsoli uruchom te polecenia, aby przejść do katalogu
public
i wyświetlić wszystkie znajdujące się w nim pliki:
cd public
ls -lh
Skompresowana wersja pakietu brotli, main.bundle.js.br
, również jest teraz zapisywana tutaj. Jest ona o około 76% mniejsza (225 KB w porównaniu z 53 KB) niż main.bundle.js
.
Następnie poproś serwer, aby wysyłał te pliki skompresowane w postaci brotli za każdym razem, gdy wymagane jest ich oryginalne wersje JS. Możesz to zrobić, definiując nową trasę w server.js
, zanim pliki zostaną udostępnione za pomocą express.static
.
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'));
app.get
informuje serwer, jak ma odpowiedzieć na żądanie GET
dotyczące określonego punktu końcowego. Za pomocą funkcji wywołania zwrotnego można następnie określić sposób obsługi tego żądania. Trasa działa w następujący sposób:
- Jeśli jako pierwszy argument określisz
'*.js'
, będzie to działać w przypadku każdego punktu końcowego, który uruchamia się w celu pobrania pliku JS. - W wywołaniu zwrotnym adres
.br
jest dołączony do adresu URL żądania, a nagłówek odpowiedziContent-Encoding
jest ustawiony nabr
. - Nagłówek
Content-Type
jest ustawiony naapplication/javascript; charset=UTF-8
w celu określenia typu MIME. next()
dba też o to, aby sekwencja obejmowała kolejne wywołania zwrotne.
Niektóre przeglądarki mogą nie obsługiwać kompresji brotli, więc zanim zwrócisz plik skompresowany z brotli, sprawdź, czy jest ona obsługiwana. Aby to zrobić, sprawdź, czy nagłówek żądania Accept-Encoding
zawiera parametr br
:
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'));
Po ponownym załadowaniu aplikacji przyjrzyj się jeszcze raz panelowi Network (Sieć).
Success! Udało Ci się użyć kompresji Brotli, aby jeszcze bardziej skompresować swoje zasoby.
Podsumowanie
To ćwiczenie z programowania pokazuje, jak brotli
może jeszcze bardziej zmniejszyć ogólny rozmiar aplikacji. Tam, gdzie jest obsługiwany, algorytm brotli
jest bardziej zaawansowany niż gzip
.