Zoptymalizuj kodowanie i rozmiar transferu zasobów tekstowych

Oprócz wyeliminowania niepotrzebnych pobrań zasobów najlepszą rzeczą, jaką możesz zrobić, aby przyspieszyć wczytywanie strony, jest zminimalizowanie ogólnego rozmiaru pobieranych danych przez optymalizację i kompresję pozostałych zasobów.

Podstawy kompresji danych

Po skonfigurowaniu witryny tak, aby nie pobierała nieużywanych zasobów, następnym krokiem jest skompresowanie pozostałych kwalifikujących się zasobów, które przeglądarka musi pobrać. W zależności od typu zasobu (tekst, obrazy, czcionki itp.) można wybrać różne techniki: ogólne narzędzia, które można włączyć na serwerze WWW, optymalizacje wstępnego przetwarzania dla określonych typów treści oraz optymalizacje specyficzne dla zasobów, które wymagają danych wejściowych od dewelopera.

Aby uzyskać najlepszą wydajność, należy połączyć wszystkie te techniki:

  • Kompresja to proces kodowania informacji przy użyciu mniejszej liczby bitów.
  • Usunięcie niepotrzebnych danych zawsze przynosi najlepsze wyniki.
  • Istnieje wiele różnych technik i algorytmów kompresji.
  • Aby uzyskać najlepszą kompresję, musisz zastosować różne techniki.

Proces zmniejszania rozmiaru danych to kompresja danych. Wiele osób przyczyniło się do opracowania algorytmów, technik i optymalizacji, które poprawiają współczynniki kompresji, szybkość kompresji i pamięć wymaganą przez różne algorytmy kompresji.

Pełne omówienie kompresji danych wykracza poza zakres tego przewodnika. Warto jednak wiedzieć, jak ogólnie działa kompresja i jakie techniki można stosować, aby zmniejszyć rozmiar różnych zasobów wymaganych przez strony.

Aby zilustrować podstawowe zasady tych technik, rozważmy proces optymalizacji prostego formatu wiadomości tekstowej, który został wymyślony na potrzeby tego przykładu:

# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
  1. Wiadomości mogą zawierać dowolne adnotacje, czasami nazywane komentarzami, które są oznaczone prefiksem „#”. Adnotacje nie wpływają na znaczenie wiadomości ani na jej zachowanie.
  2. Wiadomości mogą zawierać nagłówki, czyli pary klucz-wartość (oddzielone znakiem ":" w poprzednim przykładzie), które pojawiają się na początku wiadomości.
  3. Wiadomości zawierają ładunki tekstowe.

Co można zrobić, aby zmniejszyć rozmiar poprzedniej wiadomości, która zaczyna się od 200 znaków?

  1. Komentarz jest interesujący, ale nie wpływa na znaczenie wiadomości. Usuń go podczas przesyłania wiadomości.
  2. Istnieją dobre techniki skutecznego kodowania nagłówków. Jeśli na przykład wiesz, że wszystkie wiadomości mają „format” i „datę”, możesz przekonwertować je na krótkie identyfikatory liczb całkowitych i wysłać tylko je. Może to jednak nie być prawda, więc na razie lepiej zostawić to w spokoju.
  3. Ładunek zawiera tylko tekst. Nie wiemy, co tak naprawdę zawiera (najwyraźniej używa "secret-cipher"), ale patrząc na tekst, widzimy, że jest w nim dużo nadmiarowości. Zamiast wysyłać powtarzające się litery, można po prostu policzyć liczbę powtarzających się liter i zakodować je w bardziej efektywny sposób. Na przykład "AAA" zmieni się na "3A", co oznacza sekwencję 3 liter A.

Połączenie tych technik daje taki wynik:

format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A

Nowa wiadomość ma 56 znaków, co oznacza, że udało Ci się skrócić pierwotną wiadomość o 72%. To znaczne zmniejszenie.

To prosty przykład pokazujący, jak algorytmy kompresji mogą skutecznie zmniejszać rozmiar transferu zasobów tekstowych. W praktyce algorytmy kompresji są znacznie bardziej zaawansowane niż w poprzednim przykładzie, a w internecie można ich używać do znacznego skrócenia czasu pobierania zasobów. Dzięki zastosowaniu kompresji do zasobów tekstowych strona internetowa może poświęcać mniej czasu na wczytywanie zasobów, dzięki czemu użytkownicy mogą zobaczyć efekty tych zasobów szybciej niż bez kompresji.

Minifikacja: wstępne przetwarzanie i optymalizacje zależne od kontekstu

Pierwszą techniką, którą tu omówimy, jest minifikacja. Chociaż minifikacja nie jest ściśle algorytmem kompresji, jest sposobem na usunięcie niepotrzebnych i zbędnych znaków używanych w kodzie źródłowym, aby zasoby były bardziej czytelne dla ludzi. Jednak ta czytelność nie jest konieczna do utrzymania funkcjonalności kodu źródłowego w witrynach produkcyjnych i może opóźniać wczytywanie zasobów w internecie.

Minifikacja to rodzaj optymalizacji związanej z treścią, która może znacznie zmniejszyć rozmiar dostarczanych zasobów. Optymalizacje najlepiej stosować w ramach procesu kompilacji i wdrażania. Na przykład bundlery to powszechnie używany typ oprogramowania, które może automatycznie minifikować zasoby tuż przed wdrożeniem nowego kodu produkcyjnego w witrynie.

Najlepszym sposobem na kompresję zbędnych lub niepotrzebnych danych jest ich usunięcie. Nie możesz jednak usunąć dowolnych danych. Jednak w niektórych kontekstach, w których mamy wiedzę o formacie danych i jego właściwościach, możliwe jest znaczne zmniejszenie rozmiaru ładunku bez wpływu na jego rzeczywiste znaczenie lub możliwości.

<html>
  <head>
    <style>
      /* awesome-container is only used on the landing page */
      .awesome-container {
        font-size: 120%;
      }

      .awesome-container {
        width: 50%;
      }
    </style>
  </head>
  <body>
    <!-- awesome container content: START -->
    <div>
      This is my awesome container, and it is <em>so</em> awesome.
    </div>
    <!-- awesome container content: END -->
    <script>
      awesomeAnalytics(); // Beacon conversion metrics
    </script>
  </body>
</html>

Weźmy pod uwagę poprzedni fragment kodu HTML i 3 różne typy treści, które zawiera:

  1. Znaczniki HTML.
  2. CSS do dostosowywania prezentacji strony.
  3. JavaScript do obsługi interakcji i innych zaawansowanych funkcji strony.

Każdy z tych typów treści ma inne reguły dotyczące tego, co stanowi prawidłową treść, inne reguły dotyczące określania komentarzy itd. Pozostaje jednak pytanie, jak można zmniejszyć rozmiar tej strony.

  • Komentarze w kodzie są bardzo przydatne dla programistów, ale przeglądarka ich nie potrzebuje. Usunięcie komentarzy CSS (/* ... */), HTML (<!-- ... -->) i JavaScript (// ...) zmniejsza łączny rozmiar transferu strony i jej zasobów podrzędnych.
  • „Inteligentny” kompresor CSS może zauważyć, że używamy nieefektywnego sposobu definiowania reguł dla elementu .awesome-container, i połączyć obie deklaracje w jedną bez wpływu na inne style, co pozwoli zaoszczędzić więcej bajtów. W przypadku dużego zbioru reguł CSS usunięcie tego rodzaju nadmiarowości może przynieść zauważalne korzyści, ale nie zawsze można to zrobić, ponieważ selektory są często powielane w różnych kontekstach, np. w zapytaniach o media.
  • Spacje i tabulatory są ułatwieniem dla programistów w językach HTML, CSS i JavaScript. Dodatkowy kompresor może usunąć wszystkie karty i spacje. W przeciwieństwie do innych technik deduplikacji ten rodzaj optymalizacji można stosować dość agresywnie, o ile takie spacje lub tabulatory nie są niezbędne do wyświetlania strony – na przykład warto zachować spacje w ciągach tekstu w dokumencie HTML, ponieważ zapewniają one czytelność treści, które użytkownicy będą faktycznie widzieć.
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>

Po wykonaniu poprzednich kroków liczba znaków na stronie zmniejsza się z 516 do 204, co oznacza oszczędność około 60%. Nie jest on zbyt czytelny, ale nie musi być, aby można było go używać. Nowoczesne metody programistyczne pozwalają też zachować dobrze sformatowane i czytelne wersje kodu źródłowego oddzielnie od dobrze zoptymalizowanego kodu, który jest wdrażany w środowisku produkcyjnym. W połączeniu z mapami źródłowymi, które zapewniają czytelną reprezentację przekształconego kodu produkcyjnego, co ułatwia rozwiązywanie problemów z błędami w środowisku produkcyjnym, możesz zapewnić deweloperom dobre wrażenia, jednocześnie optymalizując wydajność pod kątem wygody użytkowników.

Poprzedni przykład ilustruje ważną kwestię: kompresor do zwykłych obciążeń, np. przeznaczony do kompresowania dowolnego tekstu, może całkiem dobrze skompresować stronę z poprzedniego przykładu, ale nigdy nie będzie wiedział, jak usunąć komentarze, zwinąć reguły CSS ani wykonać dziesiątek innych optymalizacji związanych z treścią. Dlatego tak ważne są wstępne przetwarzanie, minifikacja i inne optymalizacje uwzględniające kontekst.

Podobnie opisane powyżej techniki można rozszerzyć poza komponenty tekstowe. Obrazy, filmy i inne typy treści zawierają własne formy metadanych i różne ładunki. Na przykład gdy robisz zdjęcie aparatem, plik zwykle zawiera wiele dodatkowych informacji: ustawienia aparatu, lokalizację itp. W zależności od aplikacji te dane mogą być kluczowe (np. w przypadku witryny do udostępniania zdjęć) lub całkowicie bezużyteczne. Zastanów się, czy warto ją usunąć. W praktyce te metadane mogą zwiększyć rozmiar każdego obrazu nawet o kilkadziesiąt kilobajtów.

Krótko mówiąc, pierwszym krokiem do optymalizacji wydajności zasobów jest utworzenie spisu różnych typów treści i zastanowienie się, jakie optymalizacje dotyczące konkretnych treści można zastosować, aby zmniejszyć ich rozmiar. Gdy już je określisz, zautomatyzuj te optymalizacje, dodając je do etapów kompilacji i publikacji, aby mieć pewność, że będą one stosowane konsekwentnie w przypadku każdej nowej wersji produkcyjnej.

Kompresja tekstu za pomocą algorytmów kompresji

Kolejnym krokiem do zmniejszenia rozmiaru komponentów tekstowych jest zastosowanie do nich algorytmu kompresji. Idzie o krok dalej, agresywnie wyszukując powtarzalne wzorce w ładunkach tekstowych przed wysłaniem ich do użytkownika i dekompresując je, gdy dotrą do przeglądarki użytkownika. W efekcie rozmiar tych zasobów jest jeszcze mniejszy, a czas pobierania – krótszy.

  • gzip i Brotli to powszechnie używane algorytmy kompresji, które najlepiej sprawdzają się w przypadku zasobów tekstowych: CSS, JavaScript i HTML.
  • Wszystkie nowoczesne przeglądarki obsługują kompresję gzip i Brotli oraz informują o tym w nagłówku żądania HTTP Accept-Encoding.
  • Serwer musi być skonfigurowany tak, aby umożliwiał kompresję. Oprogramowanie serwera WWW często domyślnie włącza moduły kompresujące zasoby tekstowe.
  • Zarówno gzip, jak i Brotli można dostosować, aby poprawić współczynniki kompresji przez dostosowanie poziomu kompresji. W przypadku gzip ustawienia kompresji mieszczą się w zakresie od 1 do 9, przy czym 9 to najlepsza wartość. W przypadku Brotli zakres ten wynosi od 0 do 11, przy czym 11 to najlepsza wartość. Jednak wyższe ustawienia kompresji wymagają więcej czasu. W przypadku zasobów, które są kompresowane dynamicznie, czyli w momencie wysłania żądania, ustawienia w środku zakresu zwykle zapewniają najlepszy kompromis między współczynnikiem kompresji a szybkością. Możliwa jest jednak kompresja statyczna, czyli kompresja odpowiedzi z wyprzedzeniem, dzięki czemu można użyć najbardziej agresywnych ustawień kompresji dostępnych dla każdego algorytmu kompresji.
  • Sieci dostarczania treści (CDN) często oferują automatyczną kompresję odpowiednich zasobów. Sieci CDN mogą też zarządzać kompresją dynamiczną i statyczną, dzięki czemu nie musisz się o nią martwić.

gzip i Brotli to popularne kompresory, które można zastosować do dowolnego strumienia bajtów. W tle zapamiętują niektóre z wcześniej sprawdzonych treści pliku, a następnie próbują znaleźć i skutecznie zastąpić zduplikowane fragmenty danych.

W praktyce zarówno gzip, jak i Brotli najlepiej sprawdzają się w przypadku treści tekstowych, często osiągając współczynniki kompresji rzędu 70–90% w przypadku większych plików. Jednak uruchomienie tych algorytmów na zasobach, które są już skompresowane przy użyciu alternatywnych algorytmów (np. większości formatów plików graficznych, które używają technik kompresji bezstratnej lub stratnej), nie przynosi żadnej poprawy.

Wszystkie nowoczesne przeglądarki informują o obsłudze formatów gzip i Brotli w nagłówku żądania HTTP Accept-Encoding. Jednak to dostawca usług hostingowych musi zadbać o to, aby serwer WWW był prawidłowo skonfigurowany do udostępniania skompresowanego zasobu, gdy klient o niego poprosi.

Plik Algorytm Rozmiar bez kompresji Rozmiar po kompresji Stopień sprężania
angular-1.8.3.js Brotli 1346 KiB 256 KiB 81%
angular-1.8.3.js gzip 1346 KiB 329 KiB 76%
angular-1.8.3.min.js Brotli 173 KiB 53 KiB 69%
angular-1.8.3.min.js gzip 173 KiB 60 KiB 65%
jquery-3.7.1.js Brotli 302 KiB 69 KiB 77%
jquery-3.7.1.js gzip 302 KiB 83 KiB 73%
jquery-3.7.1.min.js Brotli 85 KiB 27 KiB 68%
jquery-3.7.1.min.js gzip 85 KiB 30 KiB 65%
lodash-4.17.21.js Brotli 531 KiB 73 KiB 86%
lodash-4.17.21.js gzip 531 KiB 94 KiB 82%
lodash-4.17.21.min.js Brotli 71 KiB 23 KiB 68%
lodash-4.17.21.min.js gzip 71 KiB 25 KiB 65%

Tabela powyżej pokazuje oszczędności, jakie można uzyskać dzięki kompresji Brotli i gzip w przypadku kilku znanych bibliotek JavaScriptu. Oszczędności wynoszą od 65% do 86% w zależności od pliku i algorytmu. Dla porównania, w przypadku obu algorytmów (Brotli i gzip) do każdego pliku zastosowano maksymalny poziom kompresji. W miarę możliwości preferuj Brotli zamiast gzip.

Włączenie kompresji to jedna z najprostszych i najskuteczniejszych optymalizacji, które można wdrożyć. Jeśli Twoja witryna nie korzysta z tej funkcji, tracisz dużą szansę na poprawę wydajności dla użytkowników. Na szczęście wiele serwerów WWW udostępnia domyślne konfiguracje, które umożliwiają tę ważną optymalizację, a sieci CDN są szczególnie skuteczne we wdrażaniu jej w sposób, który równoważy szybkość i współczynnik kompresji.

Szybkim sposobem na sprawdzenie kompresji w działaniu jest otwarcie Narzędzi deweloperskich w Chrome, otwarcie panelu Sieć, wczytanie wybranej strony i obserwowanie samego dołu panelu sieci.

Odczyt rzeczywistego i przesyłanego rozmiaru w Narzędziach deweloperskich.
Rozmiar transferu (czyli skompresowany) wszystkich zasobów strony w porównaniu z ich rzeczywistym rozmiarem, jak pokazano w panelu sieci w Narzędziach deweloperskich w Chrome.

Podobnie jak na poprzednim obrazie, powinny być widoczne te informacje:

  • Liczba żądań, czyli liczba zasobów wczytanych na stronie.
  • Rozmiar transferu wszystkich żądań. Odzwierciedla to skuteczność kompresji zastosowanej do dowolnego zasobu strony.
  • Rozmiar zasobów wszystkich żądań. Odzwierciedla to rozmiar zasobów strony po dekompresji.

Wpływ na Core Web Vitals

Poprawy skuteczności nie można zmierzyć, jeśli nie ma danych, które ją odzwierciedlają. Inicjatywa Core Web Vitals ma na celu tworzenie i zwiększanie świadomości na temat danych, które odzwierciedlają rzeczywiste wrażenia użytkowników. W odróżnieniu od wskaźników takich jak czas wczytywania strony, które nie przekładają się bezpośrednio na jakość wrażeń użytkownika,

Gdy zastosujesz optymalizacje opisane w tym przewodniku do zasobów w witrynie, efekty w przypadku wskaźników Core Web Vitals mogą się różnić w zależności od zoptymalizowanych zasobów i danych. Oto kilka przykładów, w których zastosowanie tych optymalizacji może poprawić podstawowe wskaźniki internetowe witryny:

  • Zasoby HTML, które są zminimalizowane i skompresowane, mogą poprawić wczytywanie tego kodu HTML, wykrywalność jego zasobów podrzędnych, a tym samym ich wczytywanie. Może to być korzystne dla największego wyrenderowania treści (LCP) strony. Wskazówki dotyczące zasobów, takie jak rel="preload", mogą wpływać na wykrywalność zasobów, ale użycie zbyt wielu z nich może powodować problemy z rywalizacją o przepustowość. Dzięki skompresowaniu odpowiedzi HTML na żądanie nawigacji zasoby w niej zawarte mogą zostać jak najszybciej wykryte przez skaner wstępnego wczytywania.
  • Niektóre elementy kandydujące do LCP można też szybciej wczytywać, stosując kompresję. Na przykład czas wczytywania zasobów obrazów SVG, które są kandydatami do LCP, można skrócić dzięki kompresji tekstowej. Różni się to od optymalizacji, które można wprowadzić w przypadku innych typów obrazów, które są kompresowane za pomocą innych metod, np. obrazów JPEG, które używają kompresji stratnej.
  • Ponadto węzły tekstowe mogą być też kandydatami do LCP. Sposób stosowania technik opisanych w tym przewodniku zależy od tego, czy używasz czcionki internetowej do tekstu na stronach internetowych. Jeśli używasz czcionki internetowej, obowiązują sprawdzone metody optymalizacji czcionek internetowych. Jeśli jednak nie używasz czcionek internetowych, ale czcionek systemowych, które wyświetlają się bez obciążania zasobów, minifikacja i kompresja kodu CSS skracają ten czas, co oznacza, że renderowanie potencjalnych węzłów tekstowych LCP może nastąpić wcześniej.

Podsumowanie

Sposób optymalizacji kodowania i przesyłania zasobów tekstowych to podstawowa koncepcja dotycząca wydajności, ale ma ona duży wpływ na wyniki. Upewnij się, że robisz wszystko, co możliwe, aby zasoby, które kwalifikują się do minifikacji i kompresji, korzystały z tych optymalizacji.

Co ważniejsze, upewnij się, że te procesy są zautomatyzowane. W przypadku minifikacji użyj pakietu, aby zastosować minifikację do odpowiednich zasobów. Upewnij się, że konfiguracja serwera WWW obsługuje kompresję, a ponadto używaj najskuteczniejszej dostępnej kompresji. Aby maksymalnie uprościć ten proces, użyj sieci CDN do automatyzacji kompresji, ponieważ nie tylko mogą kompresować zasoby, ale mogą to robić bardzo szybko.

Dzięki wdrożeniu tych podstawowych koncepcji dotyczących wydajności w architekturze witryny możesz mieć pewność, że działania związane z optymalizacją wydajności będą miały solidne podstawy, a kolejne optymalizacje będą opierać się na sprawdzonych metodach.