Ogólne kwestie związane z wydajnością kodu HTML

Pierwszym krokiem w tworzeniu witryny, która szybko się ładuje, jest szybkie otrzymanie odpowiedzi od serwera w celu uzyskania kodu HTML strony. Gdy wpiszesz adres URL na pasku adresu przeglądarki, przeglądarka wysyła do serwera żądanie GET, aby go pobrać. Pierwsze żądanie strony internetowej dotyczy zasobu HTML. Kluczowym celem w zakresie wydajności jest szybkość dostarczania kodu HTML przy minimalnych opóźnieniach.

Wstępne żądanie kodu HTML składa się z kilku etapów i wymaga czasu. Skrócenie czasu potrzebnego na wykonanie poszczególnych kroków skraca czas do pierwszego bajtu (TTFB). Chociaż TTFB nie jest jedynym wskaźnikiem, na którym należy się skupić, jeśli chodzi o szybkość wczytywania stron, wysoki współczynnik ten utrudnia osiągnięcie wyznaczonych progów „dobrych” dla takich danych jak największe wyrenderowanie treści (LCP) i pierwsze wyrenderowanie treści (FCP).

Zminimalizuj przekierowania

Po otrzymaniu żądania zasobu serwer może odpowiedzieć przekierowaniem – może to być przekierowanie trwałe (odpowiedź 301 Moved Permanently) lub tymczasowe (odpowiedź 302 Found).

Przekierowania spowalniają wczytywanie strony, ponieważ przeglądarka wymaga od przeglądarki wysłania dodatkowego żądania HTTP w nowej lokalizacji w celu pobrania zasobu. Są 2 rodzaje przekierowań:

  1. Przekierowania z tej samej domeny, które występują wyłącznie w Twoim źródle. Masz pełną kontrolę nad tymi typami przekierowań, ponieważ logika zarządzania nimi odbywa się całkowicie na Twoim serwerze WWW.
  2. Przekierowania między domenami inicjowane przez inne źródło. Tego rodzaju przekierowania zwykle nie mają wpływu na Twoją kontrolę.

Przekierowania między domenami są często używane przez reklamy, usługi skracania adresów URL i inne usługi innych firm. Mimo że przekierowania z innych domen są poza Twoją kontrolą, być może warto sprawdzić, czy nie masz wielu przekierowań – na przykład nie stosować reklam, które prowadzą do strony HTTP, która z kolei przekierowuje do swojego odpowiednika HTTPS, czy też przekierowania z innych domen, które odsyła do źródła, które następnie wywołuje przekierowanie z tej samej domeny.

Zapisywanie odpowiedzi HTML w pamięci podręcznej

Zapisywanie odpowiedzi HTML w pamięci podręcznej jest trudne, ponieważ odpowiedź może zawierać linki do innych kluczowych zasobów, takich jak pliki CSS, JavaScript, obrazy i inne typy zasobów. Nazwy tych zasobów mogą zawierać unikalny odcisk cyfrowy, który zmienia się w zależności od zawartości pliku. Oznacza to, że po wdrożeniu dokument HTML zapisany w pamięci podręcznej może stać się nieaktualny, ponieważ zawiera odwołania do nieaktualnych zasobów podrzędnych.

Krótki okres przechowywania w pamięci podręcznej może mieć jednak zalety, na przykład możliwość zapisywania zasobu w pamięci podręcznej w sieci CDN, co zmniejsza liczbę żądań wysyłanych z serwera pierwotnego i w przeglądarce, dzięki czemu zasoby mogą być ponownie weryfikowane, a nie pobierane ponownie. To podejście sprawdza się najlepiej w przypadku treści statycznych, które nie zmieniają się w żadnym kontekście. Odpowiedni czas przechowywania zasobów w pamięci podręcznej można ustawić na dowolną liczbę minut. Poświęć 5 minut na przygotowanie statycznych zasobów HTML i zapewnisz sobie, że okresowe aktualizacje nie zostaną zauważone.

Jeśli zawartość HTML strony jest w jakiś sposób spersonalizowana, np. pod kątem uwierzytelnionego użytkownika, najprawdopodobniej nie chcesz jej buforować ze względu na różne kwestie, np. bezpieczeństwo i aktualność. Jeśli odpowiedź HTML jest zapisywana w pamięci podręcznej przeglądarki użytkownika, nie można jej unieważnić. W takich przypadkach najlepiej unikać buforowania kodu HTML.

Ostrożnym sposobem buforowania kodu HTML jest użycie nagłówków odpowiedzi ETag lub Last-Modified. Nagłówek ETag (inaczej nazywany tagiem jednostki) to identyfikator, który w sposób unikalny reprezentuje żądany zasób. Często używa szyfrowania zawartości zasobu:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Po każdej zmianie zasobu musi zostać wygenerowana nowa wartość ETag. W kolejnych żądaniach przeglądarka wysyła wartość ETag za pomocą nagłówka żądania If-None-Match. Jeśli ETag na serwerze jest zgodny z adresem wysłanym przez przeglądarkę, serwer odpowiada, wysyłając odpowiedź 304 Not Modified, a przeglądarka korzysta z zasobu z pamięci podręcznej. Chociaż nadal wiąże się to z opóźnieniami sieciowymi, odpowiedź 304 Not Modified jest znacznie mniejsza niż cały zasób HTML.

Jednak opóźnienia sieciowe związane z ponowną weryfikacją aktualności zasobu są nadal negatywnym zjawiskiem. Podobnie jak w przypadku wielu innych aspektów tworzenia stron internetowych, komunikacje i kompromisy są nieuniknione. Od Ciebie zależy, czy warto włożyć dodatkowy wysiłek do zapisywania kodu HTML w pamięci podręcznej w ten sposób czy lepiej pozostać bez obaw i w ogóle nie męczyć się z buforowaniem treści HTML.

Mierz czas odpowiedzi serwera

Jeśli odpowiedź nie jest przechowywana w pamięci podręcznej, czas odpowiedzi serwera w dużym stopniu zależy od dostawcy usług hostingowych i stosu aplikacji backendu. Strona internetowa, która obsługuje odpowiedź generowaną dynamicznie, na przykład pobiera dane z bazy danych, może mieć wyższą wartość TTFB niż statyczna strona internetowa, którą można wyświetlić natychmiast bez konieczności poświęcania dużej ilości czasu na przetwarzanie danych w backendzie. Wyświetlenie wskaźnika postępu ładowania, a następnie pobranie wszystkich danych po stronie klienta ułatwia przeniesienie zadań z bardziej przewidywalnego środowiska po stronie serwera do potencjalnie nieprzewidywalnych po stronie klienta. Zminimalizowanie nakładu pracy po stronie klienta skutkuje zwykle poprawą wskaźników na użytkownika.

Jeśli użytkownicy napotykają w tym polu długi czas TTFB, za pomocą nagłówka odpowiedzi Server-Timing możesz ujawnić informacje o czasie spędzonym na serwerze:

Server-Timing: auth;dur=55.5, db;dur=220

Wartość nagłówka Server-Timing może zawierać wiele wskaźników, a także czas trwania każdego z nich. Dane te mogą być następnie zbierane od użytkowników w polu za pomocą interfejsu Navigation Timing API i analizowane w celu sprawdzenia, czy u użytkowników występują opóźnienia. W poprzednim fragmencie kodu nagłówek odpowiedzi zawiera 2 informacje o czasie:

  • Czas uwierzytelnienia użytkownika (auth), który trwał 55,5 milisekundy.
  • Czas dostępu do bazy danych (db), który trwał 220 milisekund.

Warto też sprawdzić swoją infrastrukturę hostingową i upewnić się, że masz odpowiednie zasoby do obsługi ruchu otrzymywanego w witrynie. Współdzielony dostawcy usług hostingowych często są narażeni na wysoki poziom TTFB, a specjalne rozwiązania, które zapewniają krótszy czas odpowiedzi, mogą być droższe.

Kompresja

Odpowiedzi tekstowe (np. obrazy HTML, JavaScript, CSS i SVG) należy skompresować, aby zmniejszyć rozmiar przesyłanych danych w sieci i przyspieszyć ich pobieranie. Najpopularniejsze algorytmy kompresji to gzip i Brotli. Brotli zwiększa o 15–20% skuteczność w porównaniu z kodem gzip.

Kompresja jest często konfigurowana automatycznie przez większość dostawców usług hostingowych, ale jeśli chcesz samodzielnie skonfigurować lub dostosować ustawienia kompresji, musisz pamiętać o kilku istotnych kwestiach:

  1. W miarę możliwości używaj Brotli. Jak już wspomnieliśmy, Brotli zapewnia doskonałą poprawę w porównaniu z gzip i jest obsługiwany we wszystkich popularnych przeglądarkach. Jeśli to możliwe, używaj Brotli, ale jeśli z Twojej witryny korzysta bardzo dużo użytkowników starszych przeglądarek, użyj programu gzip, ponieważ kompresja jest lepsza od braku kompresji.
  2. Rozmiar pliku ma znaczenie Bardzo małe zasoby – mniejsze niż 1 kiB – nie kompresują się zbyt dobrze, a czasem w ogóle nie kompresują. Skuteczność każdego rodzaju kompresji danych zależy od ilości danych, z którymi algorytm może pracować w celu znalezienia ich lepiej skompresowanych. Im większy plik, tym lepiej działa kompresja. Nie należy jednak przesyłać bardzo dużych zasobów ze względu na fakt, że można je efektywniej kompresować. Duże zasoby, takie jak na przykład JavaScript i CSS, potrzebują dużo więcej czasu na ich analizę i ocenę po zdekompresowaniu przez przeglądarkę. Mogą się też zmieniać częściej, nawet jeśli zmiany uległy niewielkim zmianom, ponieważ wszystkie zmiany powodują inny hasz pliku.
  3. Różnice między kompresją dynamiczną a statyczną. Kompresja dynamiczna i statyczna to różne podejścia do tego, kiedy należy skompresować zasób. Kompresja dynamiczna kompresuje zasób w momencie wysłania jego żądania, a czasem za każdym razem, gdy jest on żądany. Z drugiej strony kompresja statyczna kompresuje pliki z wyprzedzeniem, dzięki czemu nie trzeba kompresować w chwili wysyłania żądania. Kompresja statyczna eliminuje opóźnienia związane z kompresją, co może wydłużyć czas odpowiedzi serwera w przypadku kompresji dynamicznej. Zasoby statyczne (np. JavaScript, CSS i obrazy SVG) powinny być skompresowane statycznie, a zasoby HTML – zwłaszcza, jeśli są generowane dynamicznie dla uwierzytelnionych użytkowników – powinny być kompresowane dynamicznie.

Samodzielna kompresja jest nie lada wyzwaniem, dlatego najlepiej zdać się na to, by zajęła się tym sieć dystrybucji treści (CDN). Znajomość tych koncepcji pozwala jednak zorientować się, czy Twój dostawca usług hostingowych odpowiednio stosuje kompresję. Wiedza ta może Ci pomóc w znalezieniu możliwości ulepszenia ustawień kompresji tak, aby przynosiły najlepsze rezultaty w witrynie.

Sieci dostarczania treści (CDN)

Sieć dostarczania treści (CDN) to rozproszona sieć serwerów, które buforują zasoby z serwera pierwotnego, a następnie udostępniają je z serwerów brzegowych znajdujących się fizycznie bliżej użytkowników. Fizyczna odległość od użytkowników skraca czas błądzenia (RTT), a optymalizacje takie jak HTTP/2 lub HTTP/3, zapisywanie w pamięci podręcznej i kompresja pozwalają sieci CDN wyświetlać treści szybciej niż w przypadku ich pobrania z serwera pierwotnego. W niektórych przypadkach użycie CDN może znacznie poprawić TTFB witryny.

Sprawdź swoją wiedzę

Jakiego typu przekierowania masz pełną kontrolę?

Przekierowanie cross-origin.
Spróbuj ponownie.
Przekierowanie same-origin.
Dobrze!

Nagłówek Server-Timing może zawierać wiele danych.

Prawda
Dobrze!
Fałsz
Spróbuj ponownie.

Który typ serwera jest najprawdopodobniej fizycznie najbliżej Twoich użytkowników?

Serwer pierwotny Twojej witryny.
Spróbuj ponownie.
serwerów brzegowych sieci dystrybucji treści (CDN),
Dobrze!

Kolejny krok: omówienie ścieżki krytycznej

Znasz już niektóre aspekty związane z wydajnością kodu HTML witryny, możesz więc teraz zadbać o to, by strona wczytywała się tak szybko, jak to możliwe, ale to dopiero początek. W następnej kolejności omówimy teorię krytycznej ścieżki renderowania. W tym module omawiamy kluczowe zagadnienia, takie jak blokowanie renderowania i analizowania zasobów, oraz ich rolę w szybszym wyświetlaniu wstępnego renderowania stron w przeglądarce.