To ćwiczenie w Codelabs jest rozszerzeniem minifikowania 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
, w ramach tego ćwiczenia w Codelabs dowiesz się, jak kompresja Brutli może jeszcze bardziej zmniejszyć współczynniki kompresji oraz ogólny rozmiar Twojej aplikacji.
Zmierz odległość
Zanim zagłębimy się w temat optymalizacji, warto najpierw przeanalizować bieżący stan aplikacji.
- Aby udostępnić projekt do edycji, kliknij Remiksuj, aby edytować.
- Aby wyświetlić podgląd witryny, kliknij Wyświetl aplikację, a następnie naciśnij Pełny ekran .
W poprzednim ćwiczeniu z programowania dotyczącym minifikowania i kompresowania ładunków sieciowych zmniejszyliśmy rozmiar main.js
z 225 KB do 61,6 KB. Z tego ćwiczenia w Codelabs dowiesz się, jak kompresja Brotli może jeszcze bardziej zmniejszyć ten rozmiar pakietu.
Kompresja Brotli
Brotli to nowszy algorytm kompresji, który może zapewnić jeszcze lepsze wyniki kompresji tekstu niż gzip
. Według CertSimple skuteczność Brotli to:
- O 14% mniejszy niż
gzip
w przypadku JavaScriptu - O 21% mniejsza niż
gzip
w przypadku kodu HTML - O 17% mniejsza niż
gzip
w przypadku usługi porównywania cen
Aby można było używać wersji Brotli, Twój serwer musi obsługiwać protokół HTTPS. Reklamy typu Brotli są obsługiwane w najnowszych wersjach większości przeglądarek. Przeglądarki obsługujące przeglądarkę Brotli będą umieszczać w nagłówkach Accept-Encoding
ciąg br
:
Accept-Encoding: gzip, deflate, br
Używany algorytm kompresji możesz sprawdzić w polu Content-Encoding
na karcie Sieć w Narzędziach deweloperskich w Chrome (Command+Option+I
lub Ctrl+Alt+I
):
Włączam Brotli
Kompresja dynamiczna
Kompresja dynamiczna polega na kompresowaniu zasobów na bieżąco w odpowiedzi na żądanie przeglądarki.
Zalety
- Nie musisz tworzyć ani aktualizować zapisanych, skompresowanych wersji zasobów.
- Kompresja „w locie” 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ć trafienie na wydajność, gdy użytkownik czeka na skompresowanie zasobów przed ich wysłaniem przez serwer.
Dynamiczna kompresja Node/Express
Plik server.js
odpowiada za skonfigurowanie serwera węzła, 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ć plik express
i użyć oprogramowania pośredniczącego express.static
, aby wczytać wszystkie statyczne pliki HTML, JS i CSS w public/directory
(a pliki te są tworzone w pakiecie internetowym przy każdej kompilacji).
Aby mieć pewność, że wszystkie zasoby są skompresowane za pomocą narzędzia brotli za każdym razem, gdy są one wysyłane, można użyć modułu shrink-ray
. Najpierw dodaj go jako devDependency
w aplikacji 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');
Przed podłączeniem usługi express.static
dodaj ją jako oprogramowanie pośredniczące:
//...
var app = express();
// compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
Teraz załaduj ponownie aplikację i sprawdź rozmiar pakietu w panelu Sieć:
Teraz w nagłówku Content-Encoding
widać, że atrybut brotli
został zastosowany z poziomu bz
.
Rozmiar pliku main.bundle.js
został zmniejszony z 225 KB do 53,1 KB. To o około 14% mniej w porównaniu z plikiem gzip
(61,6 KB).
Kompresja statyczna
Idea kompresji statycznej polega na skompresowaniu i zapisaniu zasobów z wyprzedzeniem.
Zalety
- Czas oczekiwania związany z wysokim poziomem kompresji nie jest już problemem. Teraz nie trzeba nic robić, aby kompresować pliki na bieżąco, ponieważ teraz można je pobierać bezpośrednio.
Wady
- Zasoby muszą być skompresowane przy każdej kompilacji. Czas kompilacji może się znacznie wydłużyć w przypadku użycia wysokiego poziomu kompresji.
Kompresja statyczna z użyciem Node/Express i pakietu webpack
Kompresja statyczna obejmuje kompresowanie plików z wyprzedzeniem, dlatego ustawienia pakietu internetowego można zmienić w taki sposób, aby skompresować zasoby na etapie kompilacji. Można do tego używać obiektu brotli-webpack-plugin
.
Najpierw dodaj go jako devDependency
w aplikacji package.json
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
Tak jak w przypadku każdej innej wtyczki pakietu internetowego, zaimportuj ją do pliku konfiguracji webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
Dodaj go do tablicy wtyczek:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
Tablica wtyczek używa następujących argumentów:
asset
: nazwa zasobu docelowego.- Pole
[file]
zostało zastąpione nazwą oryginalnego pliku zasobu. test
: wszystkie zasoby pasujące do tego wyrażenia regularnego (czyli zasoby JavaScript o numerze kończącym się cyframi.js
) są przetwarzane.
Na przykład nazwa main.js
zostanie zmieniona na main.js.br
.
Przy ponownym ładowaniu aplikacji tworzona jest skompresowana wersja pakietu głównego. Otwórz konsolę Glitcha, aby zobaczyć, co znajduje się w ostatecznym katalogu public/
obsługiwanym przez serwer węzłów.
- Kliknij przycisk Narzędzia.
- Kliknij przycisk Konsola.
- Uruchom w konsoli te polecenia, aby przejść do katalogu
public
i wyświetlić wszystkie jego pliki:
cd public
ls -lh
Tutaj również została zapisana skompresowana wersja brotli pakietu main.bundle.js.br
, która jest około 76% mniejsza (225 KB zamiast 53 KB) niż main.bundle.js
.
Następnie poleć serwerowi, aby wysyłał te pliki skompresowane brotli za każdym razem, gdy zostaną zażądane ich oryginalne wersje JS. W tym celu zdefiniuj 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 odpowiedzieć na żądanie GET
dotyczące określonego punktu końcowego. Następnie za pomocą funkcji wywołania zwrotnego można określić sposób obsługi tego żądania. Trasa wygląda tak:
- Określenie
'*.js'
jako pierwszego argumentu oznacza, że działa on w przypadku każdego punktu końcowego, który jest wywoływany w celu pobrania pliku JS. - W wywołaniu zwrotnym do adresu URL żądania jest dołączony tag
.br
, a nagłówek odpowiedziContent-Encoding
ma wartośćbr
. - Aby określić typ MIME, nagłówek
Content-Type
ma wartośćapplication/javascript; charset=UTF-8
. next()
zapewnia też, że sekwencja będzie kontynuowana przy każdym wywołaniu zwrotnym.
Niektóre przeglądarki mogą nie obsługiwać kompresji brotli, dlatego przed zwróceniem pliku brotli sprawdź, czy jest on obsługiwany. W tym celu sprawdź, czy nagłówek żądania Accept-Encoding
zawiera ciąg 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 jeszcze raz przyjrzyj się panelowi Network (Sieć).
Gotowe. Do dalszego skompresowania zasobów użyto kompresji Brotli.
Podsumowanie
To ćwiczenie w Codelabs pokazuje, jak brotli
może jeszcze bardziej zmniejszyć ogólny rozmiar aplikacji. brotli
jest zaawansowanym algorytmem kompresji niż gzip
(o ile jest obsługiwany).