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 tym Codelab porównujemy algorytmy kompresji, np. gzip
, i sprawdzamy, jak kompresja Brotli (br
) może jeszcze bardziej zmniejszyć współczynniki kompresji i ogólny rozmiar aplikacji.
Zmierz odległość
Zanim zaczniesz wprowadzać optymalizacje, dobrze jest najpierw przeanalizować obecny stan aplikacji.
- Kliknij Remix to Edit (Zmiksuj do edycji), aby umożliwić edycję projektu.
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij 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. W tym laboratorium programistycznym dowiesz się, jak kompresja Brotli może jeszcze bardziej zmniejszyć rozmiar pakietu.
Kompresja Brotli
Brotli to nowszy algorytm kompresji, który może zapewnić jeszcze lepsze wyniki kompresji tekstu niż gzip
. Według CertSimple wydajność Brotli:
- 14% mniejsze niż
gzip
w przypadku JavaScript - 21% mniejsze niż
gzip
w przypadku kodu HTML - 17% mniejsze niż
gzip
w przypadku kodu CSS
Aby można było używać wersji Brotli, Twój serwer musi obsługiwać protokół HTTPS. Brotli jest obsługiwany we wszystkich nowoczesnych przeglądarkach. Przeglądarki, które obsługują Brotli, będą zawierać br
w nagłówkach Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
Który algorytm kompresji jest używany, możesz sprawdzić na karcie Network (Sieć) w Narzędziach deweloperskich w Chrome (Content-Encoding
lub Ctrl+Alt+I
):
Jak włączyć Brotli
Sposób konfiguracji serwera WWW do wysyłania zasobów zakodowanych w formacie Brotli zależy od tego, jak planujesz je zakodować. Możesz dynamicznie kompresować zasoby za pomocą Brotli w momencie wysyłania żądania (dynamicznie) lub zakodować je z wyprzedzeniem, aby były już skompresowane w momencie, gdy użytkownik je zażąda (statycznie).
Kompresja dynamiczna
Kompresja dynamiczna polega na kompresowaniu zasobów na bieżąco, gdy są one żądane przez przeglądarkę.
Zalety
- Nie musisz tworzyć ani aktualizować zapisanych, skompresowanych wersji zasobów.
- Kompresowanie na bieżąco sprawdza się zwłaszcza 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 musi czekać na skompresowanie zasobów, zanim zostaną wysłane przez serwer.
Kompresja dynamiczna za pomocą Node i Express
Plik server.js
odpowiada za konfigurowanie serwera Node, na którym działa aplikacja.
const express = require('express');
const app = express();
app.use(express.static('public'));
const listener = app.listen(process.env.PORT, function() {
console.log(`Your app is listening on port ${listener.address().port}`);
});
Wszystko to polega na importowaniu express
i używaniu pośrednika express.static
do wczytywania wszystkich statycznych plików HTML, JS i CSS w public/directory
(te pliki są tworzone przez webpack przy każdym tworzeniu).
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
. Zacznij od dodania go jako devDependency
w sekcji package.json
:
"devDependencies": {
// ...
"shrink-ray": "^0.1.3"
},
I zaimportuj go do pliku serwera, server.js
:
const express = require('express');
const shrinkRay = require('shrink-ray');
Dodaj go jako element pośredniczący przed zamontowaniem express.static
:
// ...
const 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ć:
W nagłówku Content-Encoding
możesz teraz zobaczyć, że brotli
jest stosowany z bz
.
Plik main.bundle.js
został spakowany z 225 KB do 53,1 KB. Jest to o około 14% mniejszy rozmiar niż w przypadku gzip
(61,6 KB).
Kompresja statyczna
Idea kompresji statycznej polega na skompresowaniu i zapisaniu zasobów z wyprzedzeniem.
Zalety
- Opóźnienia spowodowane wysokim poziomem kompresji nie stanowią już problemu. Aby skompresować pliki, nie trzeba nic robić w locie, ponieważ można je pobrać bezpośrednio.
Wady
- Zasoby muszą być kompresowane w ramach każdej kompilacji. Czas kompilacji może się znacznie wydłużyć, jeśli używasz wysokiego poziomu kompresji.
Statyczna kompresja za pomocą Node i Express z webpack
Kompresja statyczna polega na wcześniejszym skompresowaniu plików, więc ustawienia webpacka można zmodyfikować, aby kompresować zasoby w ramach etapu kompilacji. Do tego celu możesz użyć funkcji brotli-webpack-plugin
.
Zacznij od dodania go jako devDependency
w sekcji package.json
:
"devDependencies": {
// ...
"brotli-webpack-plugin": "^1.1.0"
},
Podobnie jak w przypadku innych wtyczek webpacka, 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 wtyczki używa tych argumentów:
asset
: nazwa zasobu docelowego.[file]
zostanie zastąpiony pierwotną nazwą pliku zasobu.test
: przetwarzane są wszystkie zasoby pasujące do tego wyrażenia regularnego (czyli zasoby JavaScript kończące się na.js
).
Na przykład identyfikator main.js
zostałby zmieniony na main.js.br
.
Przy ponownym ładowaniu aplikacji tworzona jest skompresowana wersja pakietu głównego. Otwórz konsolę Glitch, aby sprawdzić, co znajduje się w plikupublic/
, który jest obsługiwany przez serwer Node.
- Kliknij przycisk Narzędzia.
- Kliknij przycisk Konsola.
- W konsoli uruchom te polecenia, aby przejść do katalogu
public
i wyświetlić wszystkie jego pliki:
cd public
ls -lh
Wersja pakietu skompresowana algorytmem brotli, main.bundle.js.br
, jest teraz również zapisywana tutaj i jest o około 76% mniejsza (225 KB w porównaniu z 53 KB) niż main.bundle.js
.
Następnie powiedz serwerowi, aby wysyłał te pliki skompresowane za pomocą Brotli, gdy tylko pojawi się żądanie ich oryginalnych wersji. Aby to zrobić, zdefiniuj nową trasę w server.js
, zanim pliki zostaną przesłane za pomocą express.static
.
const express = require('express');
const 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
służy do informowania serwera, jak ma reagować na żądanie GET
dotyczące konkretnego punktu końcowego. Następnie używa się funkcji wywołania zwrotnego, aby określić sposób obsługi tego żądania. Trasa działa w ten sposób:
- Podanie wartości
'*.js'
jako pierwszego argumentu oznacza, że ta funkcja działa w przypadku każdego punktu końcowego, który jest wywoływany w celu pobrania pliku JS. - W wywołaniu zwrotnym parametr
.br
jest dołączany do adresu URL żądania, a nagłówek odpowiedziContent-Encoding
jest ustawiony nabr
. - Aby określić typ MIME, nagłówek
Content-Type
ma wartośćapplication/javascript; charset=UTF-8
. - Na koniec
next()
zapewnia, że sekwencja będzie kontynuowana w przypadku każdego wywołania zwrotnego, które może nastąpić.
Niektóre przeglądarki mogą nie obsługiwać kompresji brotli, dlatego przed zwróceniem skompresowanego pliku brotli sprawdź, czy przeglądarka obsługuje brotli. Aby to zrobić, sprawdź, czy nagłówek Accept-Encoding
zawiera br
:
const express = require('express');
const 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'));
Gdy aplikacja zostanie ponownie załadowana, jeszcze raz sprawdź panel Sieć.
Gotowe! Użyłeś kompresji Brotli, aby jeszcze bardziej skompresować zasoby.
Podsumowanie
Ten warsztat programistyczny pokazuje, jak brotli
może jeszcze bardziej zmniejszyć rozmiar aplikacji. W przypadku obsługi brotli
jest to wydajniejszy algorytm kompresji niż gzip
.