Minifikuj i kompresuj ładunki sieciowe za pomocą narzędzia gzip

Dzięki temu ćwiczeniu w Codelabs dowiesz się, jak minifikować i kompresować JavaScript pakiet dla następującej aplikacji zwiększa wydajność strony przez zmniejszenie do rozmiaru żądania aplikacji.

Zrzut ekranu aplikacji

Zmierz odległość

Zanim zagłębimy się w temat optymalizacji, warto najpierw przeanalizować o bieżącym stanie aplikacji.

  • Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie naciśnij Pełny ekran pełny ekran

Ta aplikacja została również omówiona w sekcji „Usuwanie nieużywanych usług” Codelabs", pozwalając zagłosować na swojego faworyta. kota. 🐈

Teraz zobacz, jak duża jest ta aplikacja:

  1. Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
  2. Kliknij kartę Sieć.
  3. Zaznacz pole wyboru Wyłącz pamięć podręczną.
  4. Załaduj ponownie aplikację.

Oryginalny rozmiar pakietu w panelu Sieć

Poczyniliśmy znaczne postępy w zakresie usuwania nieużywanego kodu w Codelabs i zmniejszamy rozmiar pakietu, bo 225 KB to nadal dość duży rozmiar.

Minifikacja

Rozważ poniższy blok kodu.

function soNice() {
  let counter = 0;

  while (counter < 100) {
    console.log('nice');
    counter++;
  }
}

Jeśli ta funkcja zostanie zapisana jako samodzielny plik, rozmiar pliku wyniesie około 112 B (bajty).

Po usunięciu całej spacji wynikowy kod będzie wyglądał tak:

function soNice(){let counter=0;while(counter<100){console.log("nice");counter++;}}

Rozmiar pliku wynosi teraz około 83 B. Jeśli problem będzie się powtarzał, zmienić nazwę zmiennej i zmienić niektóre wyrażenia, końcowy kod może będzie wyglądać tak:

function soNice(){for(let i=0;i<100;)console.log("nice"),i++}

Rozmiar pliku osiągnie teraz 62 B.

Z każdym etapem kod staje się coraz trudniejszy do odczytania. Pamiętaj jednak, że funkcja Mechanizm JavaScript interpretuje każdy z nich dokładnie w ten sam sposób. korzyści z zaciemnienia kodu w ten sposób mogą pomóc zmniejszyć plik rozmiarów reklam Google Ads. Na początku nie było zbyt dużo 112 B, ale nadal było 50%,

W tej aplikacji pakiet webpack w wersji 4 jest używany jako tworzenia pakietów modułów. Konkretną wersję znajdziesz tutaj: package.json.

"devDependencies": {
  //...
  "webpack": "^4.16.4",
  //...
}

Wersja 4 domyślnie minifikuje pakiet w trybie produkcyjnym. Wykorzystuje TerserWebpackPlugin wtyczkę Terser. Terser to popularne narzędzie służące do kompresji kodu JavaScript.

Aby zobaczyć, jak wygląda zminifikowany kod, kliknij main.bundle.js, pozostając w panelu Sieć w Narzędziach deweloperskich. Teraz kliknij Odpowiedź.

Zmniejszona odpowiedź

Ostateczny kod, zminifikowany i zniekształcony, jest wyświetlany w treści odpowiedzi. Aby sprawdzić, jak duży byłby pakiet, gdyby nie został zminifikowany, otwórz webpack.config.js i zaktualizuj konfigurację mode.

module.exports = {
  mode: 'production',
  mode: 'none',
  //...

Załaduj ponownie aplikację i jeszcze raz sprawdź rozmiar pakietu za pomocą Panel Sieć w Narzędziach deweloperskich

Rozmiar pakietu: 767 KB

To spora różnica. 😅

Zanim przejdziesz dalej, cofnij te zmiany.

module.exports = {
  mode: 'production',
  mode: 'none',
  //...

Uwzględnienie procesu minimalizacji kodu w aplikacji zależy od dostępnych narzędzi których używasz:

  • Jeśli używany jest pakiet webpack w wersji 4 lub nowszej, nie musisz nic więcej robić ponieważ w trybie produkcyjnym kod jest domyślnie zminifikowany. 👍
  • Jeśli używana jest starsza wersja pakietu internetowego, zainstaluj go i dołącz TerserWebpackPlugin do procesu tworzenia pakietu internetowego. Dokumentacja szczegółowo omawia tę kwestię.
  • Istnieją też inne wtyczki do minifikacji, których można użyć zamiast nich, Na przykład BabelMinifyWebpackPlugin i ClosureCompilerPlugin.
  • Jeśli w ogóle nie korzystasz z pakietu modułów, użyj narzędzia Terser. jako narzędzie interfejsu wiersza poleceń lub uwzględnić je bezpośrednio jako zależność.

Kompresja

Mimo że termin „kompresja” jest czasami luźno używany do wyjaśnienia, zmniejsza się podczas minifikacji, ale nie jest kompresowana sens dosłowny.

Kompresja oznacza zazwyczaj kod zmodyfikowany za pomocą danych do algorytmu kompresji. W przeciwieństwie do minifikacji, która zapewnia jest prawidłowy, ale skompresowany kod należy przed użyciem zdekompresować.

Przy każdym żądaniu i odpowiedzi HTTP przeglądarki i serwery WWW mogą dodawać nagłówki do uwzględnienia dodatkowe informacje o pobieranym lub odbieranym zasobie. Może to być widoczne na karcie Headers w panelu Network (Sieć) w Narzędziach deweloperskich, gdzie 3 typy są wyświetlane:

  • General (Ogólne) oznacza ogólne nagłówki istotne dla całego żądania i odpowiedzi. interakcji.
  • W sekcji Nagłówki odpowiedzi wyświetla się lista nagłówków specyficznych dla danej odpowiedzi. z serwera.
  • W sekcji Nagłówki żądania wyświetlana jest lista nagłówków dołączonych do żądania przez komponent klienta.

Spójrz na nagłówek accept-encoding w Request Headers.

Zaakceptuj nagłówek kodowania

Pole accept-encoding jest używane przez przeglądarkę do określania, które treści z formatami kodowania czy algorytmami kompresji. Jest ich wiele algorytmów kompresji tekstu. Wyróżniamy tylko trzy, obsługiwane tutaj w przypadku kompresji (i dekompresji) żądań sieciowych HTTP:

  • Gzip (gzip): najpowszechniej wykorzystywana kompresja do interakcji z serwerem i klientem. Opiera się na rzece Deflate i jest obsługiwany we wszystkich aktualnych przeglądarkach.
  • Zdefiniowane (deflate): rzadko używane.
  • Brotli (br): nowsza kompresja algorytm, który ma na celu dalszą poprawę współczynników kompresji, co może prowadzić do jeszcze szybsze wczytywanie stron. Jest ona obsługiwana w najnowszych wersji większości przeglądarek.

Przykładowa aplikacja w tym samouczku jest taka sama jak aplikacja ukończona w Ćwiczenia z programowania dotyczące „Usuń nieużywany kod”. Wyjątkiem Jako platforma serwera używana jest teraz platforma Express. W ciągu następnych kompresję statyczną i dynamiczną.

Kompresja dynamiczna

Dynamiczna kompresja obejmuje kompresowanie zasobów na bieżąco żądania przeglądarki.

Zalety

  • Nie musisz tworzyć ani aktualizować zapisanych, skompresowanych wersji zasobów gotowe.
  • Kompresja „w czasie rzeczywistym” sprawdza się szczególnie dobrze w przypadku stron internetowych, które generowane dynamicznie.

Wady

  • Kompresowanie plików na wyższych poziomach w celu uzyskania lepszych współczynników kompresji trwa to dłużej. Może to spowodować trafienie na skuteczność, gdy użytkownik czeka, aż zasoby kompresować przed wysłaniem przez serwer.

Dynamiczna kompresja Node/Express

Plik server.js odpowiada za konfigurację serwera węzła, który hostuje aplikacji.

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);
});

Obecnie robi to tylko importowanie pliku express i używanie express.static oprogramowania pośredniczącego, by wczytywać wszystkie statyczne pliki HTML, JS i CSS w public/ (są one tworzone przez pakiet internetowy z każdą kompilacją).

Aby zapewnić, że wszystkie zasoby są skompresowane przy każdym żądaniu, komponent do kompresji. i sposobu ich wykorzystania. Najpierw dodaj go jako devDependency w aplikacji package.json:

"devDependencies": {
  //...
  "compression": "^1.7.3"
},

I zaimportuj go do pliku serwera, server.js:

const express = require('express');
const compression = require('compression');

Dodaj go jako oprogramowanie pośredniczące, zanim zostanie podłączony element express.static:

//...

const app = express();

app.use(compression());

app.use(express.static('public'));

//...

Teraz ponownie załaduj aplikację i sprawdź rozmiar pakietu w panelu Sieć.

Rozmiar pakietu z kompresją dynamiczną

Z 225 KB do 61,6 KB. content-encoding jest teraz w: Response Headers wskazuje, że serwer wysyła ten plik z kodowaniem gzip.

Nagłówek kodowania treści

Kompresja statyczna

Idea kompresji statyczna polega na skompresowaniu i zapisaniu zasobów. z wyprzedzeniem.

Zalety

  • Czas oczekiwania związany z wysokim poziomem kompresji nie jest już problemem. Nie musisz nic robić na bieżąco, aby kompresować pliki, ponieważ teraz można je pobierać bezpośrednio.

Wady

  • Zasoby muszą być skompresowane przy każdej kompilacji. Czas kompilacji może być dłuższy znacznie w przypadku zastosowania wysokiego poziomu kompresji.

Kompresja statyczna z użyciem Node/Express i pakietu webpack

Kompresja statyczna wymaga wcześniejszej kompresji plików, dlatego Webpack ustawień można modyfikować w celu skompresowania zasobów na etapie kompilacji. CompressionPlugin

Najpierw dodaj go jako devDependency w aplikacji package.json:

"devDependencies": {
  //...
  "compression-webpack-plugin": "^1.1.11"
},

Jak każdą inną wtyczkę pakietu internetowego, zaimportuj ją do pliku konfiguracji, webpack.config.js:

const path = require("path");

//...

const CompressionPlugin = require("compression-webpack-plugin");

i uwzględnij go w tablicy plugins:

module.exports = {
  //...
  plugins: [
    //...
    new CompressionPlugin()
  ]
}

Domyślnie wtyczka kompresuje pliki kompilacji za pomocą dyrektywy gzip. Sprawdź w dokumentacji aby dowiedzieć się, jak dodawać opcje, by używać innego algorytmu lub uwzględniać bądź wykluczać określonych plików.

Po ponownym załadowaniu aplikacji i ponownym skompilowaniu skompresowana wersja głównego pakietu utworzony. Otwórz konsolę błędu, aby zobaczyć, co jest w środku końcowy katalog public/ obsługiwany przez serwer węzła.

  • Kliknij przycisk Narzędzia.
  • Kliknij przycisk Konsola.
  • Uruchom w konsoli te polecenia, aby przejść na public katalogu i wyświetlić wszystkie jego pliki:
cd public
ls

Ostateczne pliki wyjściowe w katalogu publicznym

Skompresowana wersja pakietu main.bundle.js.gz, skompresowana do pliku gzip, jest teraz zapisana tutaj jako cóż. CompressionPlugin domyślnie kompresuje też kompresję index.html.

Kolejną rzeczą, jaką musisz zrobić, jest poinformowanie serwera, by wysłał . Można to zrobić definiując nową trasę w server.js, zanim pliki zostaną udostępnione express.static

const express = require('express');
const app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.gz';
  res.set('Content-Encoding', 'gzip');
  next();
});

app.use(express.static('public'));

//...

app.get służy do informowania serwera, jak odpowiedzieć na żądanie GET dla przez określony punkt końcowy. Następnie zostaje użyta funkcja wywołania zwrotnego, aby określić, jak to zrobić użytkownika. Trasa wygląda tak:

  • Określenie '*.js' jako pierwszego argumentu oznacza, że działa to w przypadku każdego który uruchamia się do pobrania pliku JS.
  • W wywołaniu zwrotnym do adresu URL żądania jest dołączony tag .gz, a tag Nagłówek odpowiedzi Content-Encoding jest ustawiony na gzip.
  • Na koniec next() dba o to, aby sekwencja była kontynuowana przy każdym wywołaniu zwrotnym. co może być następną.

Po ponownym załadowaniu aplikacji jeszcze raz przyjrzyj się panelowi Network.

Zmniejszenie rozmiaru pakietu dzięki kompresji statycznej

Tak jak wcześniej, znaczny spadek rozmiaru pakietów!

Podsumowanie

Omówiliśmy proces minifikacji i kompresowania kodu źródłowego. Obie te techniki pojawiają się domyślnie w wielu narzędziach, już dziś dostępne, warto więc sprawdzić, czy Twój łańcuch narzędzi Możesz też wdrożyć oba te procesy samodzielnie.