Zoptymalizuj kodowanie i rozmiar transferu zasobów tekstowych

Oprócz wyeliminowania niepotrzebnych zasobów do pobrania najlepsze, co możesz zrobić, aby przyspieszyć wczytywanie strony, to zminimalizowanie rozmiaru pobierania przez zoptymalizowanie i skompresowanie pozostałych zasobów.

Podstawy kompresji danych

Gdy skonfigurujesz witrynę, aby uniknąć pobierania 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 itd. – jest wiele różnych technik do wyboru: ogólne narzędzia, które można włączyć na serwerze WWW, optymalizacje wstępne przetwarzania pod kątem określonych typów treści oraz optymalizacje uwzględniające zasoby, które wymagają interwencji programisty.

Aby uzyskać najlepszą wydajność, trzeba korzystać z podanych niżej metod:

  • Kompresja to proces kodowania informacji za pomocą mniejszej liczby bitów.
  • Eliminacja niepotrzebnych danych zawsze zapewnia najlepsze rezultaty.
  • Istnieje wiele różnych technik i algorytmów kompresji.
  • Aby uzyskać najlepszą kompresję, musisz zastosować różne techniki.

Proces zmniejszania rozmiaru danych polega na kompresji danych. Wiele osób wprowadza algorytmy, techniki i optymalizacje mające na celu poprawę współczynnika kompresji, szybkości kompresji oraz ilości pamięci wymaganej przez różne algorytmy kompresji.

Pełne omówienie kompresji danych znacznie wykracza poza zakres tego przewodnika. Ważne jest jednak, aby zrozumieć, jak działa kompresja i jakie techniki można wykorzystać, aby zmniejszyć rozmiar różnych zasobów, których wymagają strony.

Aby przedstawić główne zasady tych technik, przyjrzyjmy się procesowi optymalizacji prostego formatu wiadomości tekstowych, który został wymyślony tylko 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 (zwane czasem komentarzami) oznaczone prefiksem „#”. Adnotacje nie wpływają na znaczenie wiadomości ani na jej zachowanie.
  2. Wiadomości mogą zawierać headers, czyli pary klucz-wartość (rozdzielone znakiem ":" w poprzednim przykładzie), które pojawiają się na początku wiadomości.
  3. Wiadomości zawierają tekst.

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 ma wpływu na znaczenie komunikatu. Pozbądź się go w trakcie przesyłania wiadomości.
  2. Istnieją dobre techniki kodowania nagłówków w wydajny sposób. Na przykład, jeśli wiesz, że wszystkie wiadomości mają „format” i „datę”, możesz przekonwertować je na krótkie identyfikatory w postaci liczb całkowitych i wysłać je. Może to jednak nie być prawda, więc lepiej na razie to zostawić.
  3. Ładunek ma wyłącznie tekst. Nie wiemy, jaka jest ich zawartość (najwyraźniej korzysta z elementu "secret-cipher"), ale spójrz na tekst, aby wykazać, że jest w nim dużo zbędnych. Być może zamiast wysyłać powtarzające się litery, możesz po prostu zliczyć te litery i zakodować je bardziej efektywnie. Na przykład "AAA" zmienia się w "3A", co oznacza sekwencję 3 znaków A.

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

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

Nowa wiadomość ma 56 znaków, co oznacza, że została skompresowana o 72%. To znacznie mniejsza liczba!

Ten zabawkowy przykład pokazuje, 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 je wykorzystać 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 temu użytkownicy mogą zobaczyć efekty działania tych zasobów wcześniej niż bez kompresji.

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

Pierwsza omówiona tu metoda to minifikacja. Minimalizacja nie jest algorytmem kompresji, ale sposób na usunięcie zbędnych i zbędnych znaków używanych w kodzie źródłowym, aby zasoby były bardziej czytelne dla użytkowników. Jednak czytelność nie jest konieczna do utrzymania funkcjonalności kodu źródłowego na stronach produkcyjnych i może opóźnić wczytywanie zasobów w internecie.

Minimalizacja to typ optymalizacji pod kątem treści, który może znacznie zmniejszyć rozmiar dostarczanych zasobów. Optymalizacje najlepiej stosować w ramach procesu kompilacji i wdrażania. Na przykład programy do tworzenia pakietów to popularny typ oprogramowania, które może automatycznie zmniejszać zasoby jeszcze przed wdrożeniem w witrynie nowego kodu produkcyjnego.

Najlepszym sposobem na skompresowanie nadmiarowych lub niepotrzebnych danych jest ich wyeliminowanie. Nie możesz jednak po prostu usunąć wybranych danych. Jednak w niektórych kontekstach, gdzie dysponujemy wiedzą na temat formatu danych i jego właściwości, możemy znacznie zmniejszyć rozmiar ładunku bez wpływu na jego rzeczywiste znaczenie czy 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>

Zwróć uwagę na poprzedni fragment kodu HTML i 3 różne rodzaje treści, które zawiera:

  1. Znaczniki HTML.
  2. CSS, które pozwalają dostosować prezentację strony.
  3. JavaScript do obsługi interakcji i innych zaawansowanych funkcji stron.

Każdy z tych rodzajów treści ma różne zasady definiujące prawidłową treść, określając komentarze itd. Pozostaje jednak pytanie: jak można zmniejszyć rozmiar tej strony?

  • Komentarze do kodu są bardzo przydatne dla programisty, ale przeglądarka ich nie potrzebuje. Wycinanie komentarzy CSS (/* ... */), HTML (<!-- ... -->) i JavaScript (// ...) zmniejsza całkowity rozmiar transferu strony i jej zasobów podrzędnych.
  • „Inteligentny” kompresor CSS zauważył, że stosujemy nieefektywny sposób definiowania reguł dla .awesome-container, i zwinął 2 deklaracje w jedną, nie zmieniając stylów, co pozwoli zaoszczędzić więcej bajtów. W przypadku obszernego zestawu reguł CSS może to doprowadzić do zwrócenia tego typu nadmiarowości. Nie można tego jednak stosować mocno, ponieważ selektory są często niepotrzebnie duplikowane w różnych kontekstach, np. w zapytaniach o media.
  • Spacje i karty to ułatwienia dla programistów w przypadku języków HTML, CSS i JavaScript. Dodatkowy kompresor może usunąć wszystkie tabulatury i spacje. W odróżnieniu od innych technik duplikowania ten rodzaj optymalizacji można zastosować dość agresywnie, o ile takie spacje i tabulatory nie są niezbędne do prezentacji strony. Warto na przykład zachować odstępy w sekwencjach tekstu w dokumencie HTML, ponieważ zapewniają one czytelność treści, którą użytkownicy faktycznie zobaczą.
<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 zastosowaniu poprzednich kroków długość strony zostaje zmniejszona z 516 do 204 znaków, co stanowi około 60% oszczędności. Nie jest on zbyt czytelny, ale nie musi być łatwo dostępny. Nowoczesne metody programowania pozwalają również oddzielić dobrze sformatowane i czytelne wersje kodu źródłowego od dobrze zoptymalizowanego kodu wysyłanego do produkcji. W połączeniu z mapami źródłowymi, które oferują czytelny obraz przekształconego kodu produkcyjnego, ułatwiają rozwiązywanie problemów z błędami w środowisku produkcyjnym. Zapewniają one pozytywne wrażenia programistów i optymalizują wydajność z myślą o wrażeniach użytkowników.

Poprzedni przykład ilustruje ważną kwestię: zwykły kompresor (np. przeznaczony do kompresowania dowolnego tekstu) w poprzednim przykładzie mógłby całkiem nieźle skompresować stronę, ale nigdy nie wiedziałby o usunięciu komentarzy, zwinięciu reguł CSS czy dziesiątkach innych optymalizacji związanych z treścią. Dlatego tak ważne są wstępne przetwarzanie, minifikacja i inne optymalizacje zależne od kontekstu.

I analogicznie, opisane techniki można rozszerzyć poza zasoby tekstowe. Obrazy, filmy i inne rodzaje treści zawierają własne formy metadanych i różne ładunki. Na przykład za każdym razem, gdy robisz zdjęcie aparatem, w pliku zazwyczaj znajduje się wiele dodatkowych informacji: ustawienia kamery, lokalizacja itp. W zależności od aplikacji dane mogą być kluczowe (np. witryna do udostępniania zdjęć) lub zupełnie bezużyteczne. Zastanów się, czy warto usuwać te treści. W praktyce łączny rozmiar obrazu może wynosić nawet dziesiątki kilobajtów.

Krótko mówiąc, pierwszym krokiem na drodze do optymalizacji efektywności zasobów jest stworzenie spisu treści dla różnych typów treści i zastanowienie się, jakie optymalizacje pod kątem treści możesz zastosować, aby zmniejszyć ich rozmiar. Następnie, gdy już je poznasz, zautomatyzuj te optymalizacje, dodając je do kroków kompilacji i wersji. Dzięki temu będziesz mieć pewność, że optymalizacje są stosowane konsekwentnie w przypadku każdej nowej wersji produkcyjnej.

Kompresja tekstu za pomocą algorytmów kompresji

Następnym krokiem do zmniejszenia rozmiaru zasobów tekstowych jest zastosowanie do nich algorytmu kompresji. To idzie o krok dalej, polegając na agresywnym wyszukiwaniu powtarzających się wzorców w ładunkach tekstowych przed wysłaniem ich do użytkownika i dekompresowaniu ich po tym, jak znajdą się w przeglądarce użytkownika. Efektem jest dalsze i znaczne zmniejszenie tych zasobów oraz skrócenie czasu pobierania.

  • 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. Obie te formaty będą reklamowane w nagłówku żądania HTTP Accept-Encoding.
  • Musisz skonfigurować serwer pod kątem włączenia kompresji. Oprogramowanie serwera WWW często domyślnie umożliwia kompresję zasobów tekstowych.
  • Zarówno gzip, jak i Brotli można dostosować, aby poprawić współczynniki kompresji dzięki dostosowaniu poziomu kompresji. W przypadku programu gzip ustawienia kompresji mieszczą się w zakresie od 1 do 9, gdzie 9 to wartość najlepsza. W przypadku Brotli zakres wynosi od 0 do 11, gdzie 11 to wartość najwyższa. Wyższe ustawienia kompresji wymagają jednak więcej czasu. W przypadku zasobów, które są skompresowane dynamicznie, czyli w momencie wysyłania żądania, ustawienia znajdujące się w środku zakresu zazwyczaj zapewniają najlepszy kompromis między współczynnikiem kompresji a szybkością. Możliwa jest jednak kompresja statyczna, która ma miejsce, gdy odpowiedź jest kompresowana z wyprzedzeniem. Dlatego można stosować najbardziej agresywne ustawienia kompresji dostępne dla poszczególnych algorytmów kompresji.
  • Sieci dostarczania treści (CDN) zwykle oferują automatyczną kompresję kwalifikujących się zasobów. Sieci CDN również zarządzają kompresją dynamiczną i statyczną, dzięki czemu masz o jeden aspekt kompresji mniej.

gzip i Brotli to popularne kompresory, które można zastosować do dowolnego strumienia bajtów. Zapamiętują one część wcześniej zbadanych treści pliku, a potem próbują znaleźć i zastąpić zduplikowane fragmenty danych w wydajny sposób.

W praktyce zarówno gzip, jak i Brotli sprawdzają się najlepiej w przypadku treści tekstowych, często osiągają współczynnik kompresji na poziomie 70–90% w przypadku większych plików. Jednak korzystanie z zasobów algorytmów, które są już skompresowane za pomocą alternatywnych algorytmów, jak w przypadku większości formatów obrazów wykorzystujących techniki kompresji bezstratnej lub stratnej, nie przynosi żadnych ulepszeń.

Wszystkie nowoczesne przeglądarki reklamują obsługę gzip i brotli w nagłówku żądania HTTP Accept-Encoding. Jednak to dostawca usług hostingowych ma obowiązek zadbać o to, aby serwer WWW został prawidłowo skonfigurowany, aby wyświetlać skompresowane zasoby, gdy klient ich zażąda.

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 poprzedniej tabeli pokazano oszczędności, jakie może przynieść kilka znanych bibliotek JavaScript zarówno przy kompresji Brotli, jak i za pomocą kompresji gzip. W zależności od pliku i algorytmu oszczędności wynoszą od 65% do 86%. Dla informacji w przypadku plików Brotli i gzip zastosowano maksymalny poziom kompresji. W miarę możliwości używaj Brotli zamiast gzip.

Włączenie kompresji jest jedną z najprostszych i najbardziej skutecznych optymalizacji. Jeżeli Twoja strona nie będzie z niego korzystać, stracisz dużą szansę na poprawę skuteczności użytkowników. Na szczęście wiele serwerów WWW udostępnia domyślne konfiguracje, które umożliwiają tę ważną optymalizację. W szczególności sieci CDN są bardzo skuteczne w implementacji w sposób zapewniający równowagę między szybkością i współczynnikiem kompresji.

Szybkim sposobem na sprawdzenie działania kompresji jest otwarcie Narzędzi deweloperskich w Chrome, otwarcie panelu Network (Sieć), wczytanie wybranej strony i sprawdzenie samego dolnej części panelu sieci.

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

Podobnie jak w przypadku poprzedniego obrazu, powinien wyświetlać się podział na następujące elementy:

  • Liczba żądań, czyli liczba wczytywanych zasobów strony.
  • Rozmiar przenoszenia wszystkich żądań. Odzwierciedla ona efektywność kompresji zastosowanej do zasobów strony.
  • Rozmiar zasobu wszystkich żądań. Wskazuje on rozmiar zasobów strony po dekompresji.

Wpływ na podstawowe wskaźniki internetowe

Wzrost skuteczności będzie możliwy tylko wtedy, gdy istnieją dane, które odzwierciedlają te ulepszenia. Inicjatywa dotycząca podstawowych wskaźników internetowych ma na celu tworzenie i zwiększanie świadomości wskaźników, które odzwierciedlają rzeczywiste wrażenia użytkowników. Jest to przeciwieństwo danych, takich jak np. prosty czas wczytywania strony, które nie mają bezpośredniego przełożenia na wygodę użytkowników.

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

  • Zmniejszone i skompresowane zasoby HTML mogą poprawić ładowanie kodu HTML i wykrywalność jego zasobów podrzędnych, a tym samym przy ich ładowaniu. Może to być przydatne w przypadku 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 ich zbyt wiele może powodować problemy z rywalizacją o przepustowość. Jeśli odpowiedź HTML na żądanie nawigacji jest skompresowana, zawarte w nich zasoby zostaną jak najszybciej wykryte przez skaner wstępnego wczytywania.
  • Niektóre kandydaty LCP można też ładować szybciej przy użyciu kompresji. Na przykład w przypadku obrazów SVG, które są kandydatami LCP, czas wczytywania zasobów można skrócić przez kompresję tekstową. Różni się to od optymalizacji, którą wprowadza się w przypadku innych typów obrazów, które są kompresowane wewnętrznie za pomocą innych metod kompresji, takich jak kompresja stratna w przypadku obrazów JPEG.
  • Poza tym węzły tekstowe mogą też być kandydatami do LCP. Sposób, w jaki techniki są opisane w tym przewodniku, zależy od tego, czy na swoich stronach internetowych używasz czcionki internetowej. Jeśli korzystasz z czcionki internetowej, zastosuj się do sprawdzonych metod optymalizacji czcionek internetowych. Jeśli jednak nie używasz czcionek internetowych, a tylko czcionek systemowych, które wyświetlają się bez wydłużania czasu wczytywania zasobów, zmniejszenie i kompresja kodu CSS skraca czas wczytywania, co oznacza, że renderowanie potencjalnych węzłów tekstowych LCP może nastąpić wcześniej.

Podsumowanie

Optymalizacja kodowania i przenoszenia zasobów tekstowych to podstawowe pojęcie dotyczące wydajności, ale ma ogromny wpływ na jego skuteczność. Upewnij się, że robisz wszystko, co w Twojej mocy, aby zasoby kwalifikujące się do minifikacji i kompresji przynosiły korzyści z tych optymalizacji.

Przede wszystkim dopilnuj, aby te procesy były zautomatyzowane. Na potrzeby minifikacji użyj narzędzia tworzenia pakietów, aby zastosować minifikację do kwalifikujących się zasobów. Upewnij się, że konfiguracja Twojego serwera WWW obsługuje kompresję, ale co więcej, używaj najskuteczniejszej dostępnej kompresji. Aby jak najbardziej uprościć ten proces, korzystaj z sieci CDN do automatyzacji kompresji, ponieważ nie tylko kompresują one zasoby, ale także bardzo szybko.

Włączając te podstawowe założenia dotyczące skuteczności w architekturę witryny, zyskujesz pewność, że Twoje działania związane z optymalizacją skuteczności będą dobrze funkcjonować, a późniejsze optymalizacje mogą opierać się na solidnych podstawach sprawdzonych metod.