Zoptymalizuj kodowanie i rozmiar transferu zasobów tekstowych

Oprócz wyeliminowania pobierania niepotrzebnych zasobów najlepszym sposobem na przyspieszenie wczytywania strony jest zminimalizowanie ogólnego rozmiaru pobierania przez optymalizację i kompresję pozostałych zasobów.

Kompresja danych: poradnik

Gdy skonfigurujesz witrynę tak, aby nie pobierała nieużywanych zasobów, kolejnym krokiem będzie 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ć wiele różnych technik: 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ą interwencji dewelopera.

Aby uzyskać najlepszą skuteczność, musisz zastosować wszystkie te techniki:

  • Kompresja to proces kodowania informacji przy użyciu mniejszej liczby bitów.
  • Usuwanie niepotrzebnych danych zawsze przynosi najlepsze rezultaty.
  • 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 opracowało algorytmy, techniki i optymalizacje, które poprawiają współczynniki kompresji, szybkość kompresji i pamięć wymaganą przez różne algorytmy kompresji.

Szczegółowe omówienie kompresji danych wykracza poza zakres tego przewodnika. Warto jednak zrozumieć, jak działa kompresja, oraz poznać techniki, których możesz użyć, aby zmniejszyć rozmiar różnych zasobów wymaganych przez Twoje 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ą oznaczane prefiksem „#”. Adnotacje nie wpływają na znaczenie wiadomości ani jej działanie.
  2. Wiadomości mogą zawierać nagłówki, czyli pary klucz-wartość (rozdzielone znakiem ":" w przykładzie powyżej), 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. wyeliminować go podczas przesyłania wiadomości.
  2. Istnieją dobre techniki wydajnego 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 całkowite i wysyłać tylko je. Może to jednak nie być prawdą, więc na razie lepiej tego nie zmieniać.
  3. Ładunek zawiera tylko tekst. Nie wiemy, co tak naprawdę zawiera ten plik (wygląda na to, że używa "secret-cipher"), ale już sam tekst pokazuje, że jest w nim dużo powtórzeń. Zamiast wysyłać powtarzające się litery, możesz po prostu zliczyć ich liczbę i zakodować je w bardziej efektywny sposób. Na przykład "AAA" zmieni się na "3A", co oznacza sekwencję trzech liter A.

Połączenie tych technik daje następujący rezultat:

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

Nowa wiadomość ma 56 znaków, co oznacza, że została skompresowana o 72%. To znaczne ograniczenie.

To przykład, który pokazuje, jak algorytmy kompresji mogą skutecznie zmniejszać rozmiar przesyłanych 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 kompresji 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 dostosowane do kontekstu

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

Minifikacja to rodzaj optymalizacji treści, która może znacznie zmniejszyć rozmiar dostarczanych zasobów. Najlepiej stosować ją w ramach procesu kompilacji i wdrażania. Na przykład narzędzia do łączenia plików to powszechnie używany rodzaj oprogramowania, które może automatycznie minimalizować zasoby tuż przed wdrożeniem nowego kodu produkcyjnego w witrynie.

Najlepszym sposobem na skompresowanie nadmiarowych lub niepotrzebnych danych jest ich usunięcie. Nie możesz jednak usuwać dowolnych danych. Jednak w niektórych kontekstach, w których mamy wiedzę o formacie danych i jego właściwościach, możemy znacznie zmniejszyć rozmiar ł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ź pod uwagę poprzedni fragment kodu HTML i 3 różne typy treści, które zawiera:

  1. Znaczniki HTML.
  2. CSS do dostosowywania wyglądu 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 określania komentarzy itp. 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. Usuwanie komentarzy CSS (/* ... */), HTML (<!-- ... -->) i JavaScript (// ...) zmniejsza całkowity rozmiar przesyłanych danych strony i jej zasobów podrzędnych.
  • „Inteligentny” kompresor CSS może zauważyć, że używamy nieefektywnego sposobu definiowania reguł dla .awesome-container, i zwinąć 2 deklaracje w 1, nie wpływając na inne style i oszczędzając więcej bajtów. W przypadku dużego zestawu reguł CSS usunięcie tego rodzaju nadmiarowości może przynieść korzyści, ale nie zawsze można je zastosować w agresywny sposób, ponieważ selektory są często powielane w różnych kontekstach, np. w zapytaniach o multimedia.
  • Spacje i tabulatory to ułatwienia dla programistów w HTML, CSS i JavaScript. Dodatkowy kompresor może usunąć wszystkie tabulatory i spacje. W przeciwieństwie do innych technik usuwania duplikatów ten rodzaj optymalizacji może być stosowany dość agresywnie, o ile 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 będą widoczne dla użytkowników.
<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 powyższych czynności liczba znaków na stronie zmniejszy się z 516 do 204, co oznacza oszczędność około 60%. Co prawda nie jest to zbyt czytelne, ale nie musi być, aby można było z tego korzystać. Nowoczesne metody programowania pozwalają też oddzielić dobrze sformatowane i czytelne wersje kodu źródłowego 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, możesz łatwiej rozwiązywać problemy w środowisku produkcyjnym. Dzięki temu możesz zapewnić zarówno wygodę programistom, jak i zoptymalizować wydajność z myślą o użytkownikach.

Poprzedni przykład ilustruje ważną kwestię: uniwersalny kompresor, np. taki, który jest przeznaczony do kompresowania dowolnego tekstu, może całkiem dobrze skompresować stronę z poprzedniego przykładu, ale nigdy nie będzie wiedział, że należy usunąć komentarze, zwinąć reguły CSS ani zastosować dziesiątek innych optymalizacji specyficznych dla treści. Dlatego tak ważne jest wstępne przetwarzanie, minimalizacja i inne optymalizacje uwzględniające kontekst.

Podobnie opisane powyżej techniki można stosować nie tylko w przypadku komponentów opartych na tekście. Obrazy, filmy i inne typy treści zawierają własne formy metadanych i różne ładunki. Na przykład za każdym razem, gdy robisz zdjęcie aparatem, plik 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 metadane mogą zajmować dziesiątki kilobajtów w przypadku każdego obrazu.

Pierwszym krokiem w optymalizacji wydajności komponentów jest utworzenie spisu różnych typów treści i zastanowienie się, jakie optymalizacje można zastosować w przypadku poszczególnych typów treści, aby zmniejszyć ich rozmiar. Następnie, po ustaleniu, jakie to optymalizacje, zautomatyzuj je, dodając je do kroków kompilacji i wdrażania, aby mieć pewność, że będą one konsekwentnie stosowane w przypadku każdej nowej wersji wdrażanej w środowisku produkcyjnym.

Kompresja tekstu za pomocą algorytmów kompresji

Kolejnym krokiem w zmniejszaniu rozmiaru komponentów tekstowych jest zastosowanie do nich algorytmu kompresji. To rozwiązanie idzie o krok dalej, ponieważ przed wysłaniem do użytkownika agresywnie wyszukuje powtarzalne wzorce w ładunkach opartych na tekście i dekompresuje je po dotarciu do przeglądarki użytkownika. W rezultacie następuje dalsze i znaczne zmniejszenie tych zasobów, a w konsekwencji szybsze pobieranie.

  • 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 obsłudze obu tych metod w nagłówku żądania HTTP Accept-Encoding.
  • Serwer musi być skonfigurowany tak, aby włączać kompresję. Oprogramowanie serwera WWW często domyślnie włącza moduły do kompresowania zasobów tekstowych.
  • Zarówno gzip, jak i Brotli można dostosować, aby poprawić współczynniki kompresji, zmieniając poziom kompresji. W przypadku kompresji gzip ustawienia kompresji mieszczą się w zakresie od 1 do 9, przy czym 9 oznacza najlepszą kompresję. W przypadku Brotli ten zakres wynosi od 0 do 11, przy czym 11 jest najlepszą wartością. Jednak wyższe ustawienia kompresji wymagają więcej czasu. W przypadku zasobów kompresowanych 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, w przypadku której odpowiedź jest kompresowana z wyprzedzeniem, dzięki czemu można używać najbardziej agresywnych ustawień kompresji dostępnych dla każdego algorytmu kompresji.
  • Sieci dostarczania treści (CDN) często oferują automatyczną kompresję kwalifikujących się zasobów. Sieci CDN mogą też zarządzać kompresją dynamiczną i statyczną, dzięki czemu nie musisz się martwić o ten aspekt kompresji.

gzipBrotli to popularne kompresory, które można zastosować do dowolnego strumienia bajtów. Zapamiętują one część wcześniej zbadanej zawartości pliku, a następnie próbują w wydajny sposób znaleźć i 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 w przypadku większych plików współczynniki kompresji na poziomie 70–90%. Jednak uruchamianie tych algorytmów na zasobach, które są już skompresowane za pomocą innych algorytmów, np. większości formatów obrazów, które korzystają z technik kompresji bezstratnej lub stratnej, daje niewielkie lub żadne korzyści.

Wszystkie nowoczesne przeglądarki informują o obsłudze gzip i Brotli w Accept-Encodingnagłówku żądania HTTP. Jednak to dostawca hostingu jest odpowiedzialny za prawidłową konfigurację serwera internetowego, aby w odpowiedzi na żądanie klienta serwował skompresowany zasób.

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%

W tabeli powyżej przedstawiono oszczędności, jakie mogą zapewnić kompresja Brotli i gzip w przypadku kilku znanych bibliotek JavaScript. Oszczędności wynoszą od 65% do 86% w zależności od pliku i algorytmu. Dla porównania do każdego pliku zastosowano maksymalny poziom kompresji w przypadku algorytmów Brotli i gzip. 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 zwiększenie wydajności dla użytkowników. Na szczęście wiele serwerów internetowych udostępnia domyślne konfiguracje, które umożliwiają tę ważną optymalizację, a w szczególności sieci CDN bardzo skutecznie wdrażają ją w sposób, który równoważy szybkość i współczynnik kompresji.

Aby szybko sprawdzić, jak działa kompresja, otwórz Narzędzia deweloperskie w Chrome, a następnie panel Sieć. Wczytaj wybraną stronę i sprawdź dolną część panelu sieci.

Odczyt w Narzędziach deweloperskich rzeczywistego rozmiaru w porównaniu z rozmiarem transferu.
Reprezentacja rozmiaru transferu (czyli skompresowanego) wszystkich zasobów strony w porównaniu z ich rzeczywistym rozmiarem, jak widać w panelu sieci Narzędzi deweloperskich w Chrome.

Podobnie jak na powyższym obrazie, powinny być widoczne te informacje:

  • Liczba żądań, czyli liczba zasobów załadowanych na stronie.
  • Rozmiar transferu wszystkich żądań. Odzwierciedla to skuteczność kompresji zastosowanej do dowolnych zasobów strony.
  • Rozmiar zasobu wszystkich żądań. Odzwierciedla to rozmiar zasobów strony po ich rozpakowaniu.

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 promowanie wskaźników, które odzwierciedlają rzeczywiste wrażenia użytkowników. Różni się to od wskaźników, które nie przekładają się bezpośrednio na jakość wrażeń użytkownika, np. prostego czasu wczytywania strony.

Gdy zastosujesz optymalizacje opisane w tym przewodniku do zasobów w swojej witrynie, wpływ na Core Web Vitals może się różnić w zależności od zoptymalizowanych zasobów i odpowiednich wskaźników. Oto jednak kilka przypadków, w których zastosowanie tych optymalizacji może poprawić podstawowe wskaźniki internetowe Twojej witryny:

  • Zminimalizowane i skompresowane zasoby HTML mogą przyspieszyć wczytywanie tego kodu HTML oraz wykrywanie jego zasobów podrzędnych, a tym samym poprawić ich wczytywanie. Może to być korzystne dla największego wyrenderowania treści (LCP) na stronie. Wskazówki dotyczące zasobów, takie jak rel="preload", mogą wpływać na wykrywalność zasobów, ale używanie zbyt wielu z nich może powodować problemy z konkurencją o przepustowość. Dzięki kompresji odpowiedzi HTML na żądanie nawigacji skaner wstępnego wczytywania może jak najszybciej wykryć zasoby w odpowiedzi.
  • Niektóre kandydaci do LCP mogą być też wczytywani szybciej dzięki kompresji. Na przykład w przypadku obrazów SVG, które są kandydatami do LCP, można skrócić czas ładowania zasobu za pomocą kompresji tekstowej. Różni się to od optymalizacji innych typów obrazów, które są kompresowane za pomocą innych metod kompresji, np. obrazów JPEG, które korzystają z kompresji stratnej.
  • Poza tym kandydatami do LCP mogą być też węzły tekstowe. Sposób wykorzystania technik opisanych w tym przewodniku zależy od tego, czy w tekście na stronach internetowych używasz czcionki internetowej. 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

Optymalizacja kodowania i przesyłania zasobów tekstowych to podstawowa koncepcja wydajności, która ma jednak duży wpływ na wyniki. Upewnij się, że robisz wszystko, co w Twojej mocy, aby zasoby kwalifikujące 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 narzędzia do łączenia plików, aby zastosować minifikację do odpowiednich zasobów. Sprawdź, czy konfiguracja serwera WWW obsługuje kompresję, a także używaj najskuteczniejszej dostępnej kompresji. Aby jak najbardziej uprościć ten proces, używaj sieci CDN do automatyzacji kompresji. Nie tylko mogą one kompresować zasoby, ale też robią to bardzo szybko.

Wprowadzając te podstawowe koncepcje dotyczące wydajności do architektury witryny, możesz mieć pewność, że Twoje działania związane z optymalizacją wydajności są dobrze ukierunkowane, a kolejne optymalizacje będą oparte na solidnych podstawach dobrych praktyk.