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

Pierwszym krokiem w tworzeniu witryny, która szybko się wczytuje, jest otrzymanie w odpowiednim czasie odpowiedzi z serwera na żądanie kodu HTML strony. Gdy wpiszesz adres URL na pasku adresu przeglądarki, przeglądarka wyśle do serwera GETżądanie, aby go pobrać. Pierwsze żądanie dotyczące strony internetowej dotyczy zasobu HTML, dlatego zapewnienie szybkiego dostarczania kodu HTML z minimalnymi opóźnieniami jest kluczowym celem związanym z wydajnością.

Wstępne żądanie kodu HTML przechodzi kilka etapów, z których każdy zajmuje trochę czasu. Skrócenie czasu poświęcanego na każdy krok przyspiesza czas do pierwszego bajtu (TTFB). TTFB nie jest jedynym wskaźnikiem, na którym należy się skupić, jeśli chodzi o szybkość wczytywania stron, ale wysoki TTFB utrudnia osiągnięcie wyznaczonych progów „dobrych” dla wskaźników takich jak największe wyrenderowanie treści (LCP)pierwsze wyrenderowanie treści (FCP).

Zminimalizuj przekierowania

Gdy zasób jest żądany, serwer może odpowiedzieć przekierowaniem, trwałym (odpowiedź 301 Moved Permanently) lub tymczasowym (odpowiedź 302 Found).

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

  1. Przekierowania z tej samej domeny, które występują w całości w obrębie Twojej domeny. Tego typu przekierowania są w pełni pod Twoją kontrolą, ponieważ logika zarządzania nimi znajduje się w całości na Twoim serwerze.
  2. Przekierowania z innej domeny inicjowane przez inną domenę. Tego typu przekierowania zwykle nie zależą od Ciebie.

Przekierowania między domenami są często używane przez reklamy, usługi skracania adresów URL i inne usługi zewnętrzne. Przekierowania między domenami są poza Twoją kontrolą, ale warto sprawdzić, czy nie występują wielokrotne przekierowania, np. reklama, która prowadzi do strony HTTP, a ta z kolei przekierowuje do jej odpowiednika HTTPS, lub przekierowanie między domenami, które prowadzi do Twojej domeny, ale następnie wywołuje przekierowanie w tej samej domenie.

Buforowanie odpowiedzi HTML

Zapisywanie w pamięci podręcznej odpowiedzi HTML jest trudne, ponieważ odpowiedź może zawierać linki do innych ważnych zasobów, takich jak CSS, JavaScript, obrazy i inne typy zasobów. Te zasoby mogą zawierać unikalny odcisk palca w nazwach plików, który zmienia się w zależności od zawartości pliku. Oznacza to, że po wdrożeniu buforowany dokument HTML może stać się nieaktualny, ponieważ będzie zawierać odwołania do nieaktualnych zasobów podrzędnych.

Krótki czas życia pamięci podręcznej – zamiast braku buforowania – może jednak przynieść korzyści, takie jak możliwość buforowania zasobu w sieci CDN, co zmniejsza liczbę żądań obsługiwanych przez serwer źródłowy, oraz w przeglądarce, co umożliwia ponowne sprawdzanie ważności zasobów zamiast ponownego ich pobierania. To podejście najlepiej sprawdza się w przypadku statycznych treści, które nie zmieniają się w żadnym kontekście. Odpowiedni czas buforowania zasobów można ustawić na liczbę minut, którą uznasz za odpowiednią. 5 minut w przypadku statycznych zasobów HTML to bezpieczna wartość, która zapewnia, że okresowe aktualizacje nie pozostaną niezauważone.

Jeśli zawartość HTML strony jest w jakiś sposób spersonalizowana, np. dla uwierzytelnionego użytkownika, prawdopodobnie nie chcesz w ogóle zapisywać treści w pamięci podręcznej z różnych powodów, w tym ze względu na bezpieczeństwo i aktualność. Jeśli odpowiedź HTML jest zapisana w pamięci podręcznej przeglądarki użytkownika, nie możesz jej unieważnić. W takich przypadkach najlepiej w ogóle unikać buforowania kodu HTML.

Ostrożne podejście do przechowywania w pamięci podręcznej plików HTML może polegać na użyciu nagłówków odpowiedzi ETag lub Last-Modified. Nagłówek ETag, czyli tag jednostki, to identyfikator, który jednoznacznie reprezentuje żądany zasób, często za pomocą skrótu zawartości zasobu:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Za każdym razem, gdy zasób ulegnie zmianie, należy wygenerować nową wartość ETag. W przypadku kolejnych żądań przeglądarka wysyła wartość ETag za pomocą If-None-Matchnagłówka żądania. Jeśli ETag na serwerze jest zgodny z wartością wysłaną przez przeglądarkę, serwer odpowiada za pomocą odpowiedzi 304 Not Modified, a przeglądarka używa zasobu z pamięci podręcznej. Chociaż nadal wiąże się to z opóźnieniem sieci, odpowiedź 304 Not Modified jest znacznie mniejsza niż cały zasób HTML.

Opóźnienie sieci związane z ponownym sprawdzaniem świeżości zasobu jest jednak pewnego rodzaju wadą. Podobnie jak w przypadku wielu innych aspektów tworzenia stron internetowych, nieuniknione są kompromisy i ustępstwa. To od Ciebie zależy, czy dodatkowy wysiłek związany z buforowaniem kodu HTML w ten sposób jest tego wart, czy lepiej zachować ostrożność i w ogóle nie buforować treści HTML.

Pomiar czasu reakcji serwera

Jeśli odpowiedź nie jest zapisana w pamięci podręcznej, czas odpowiedzi serwera w dużej mierze zależy od dostawcy hostingu i stosu aplikacji backendowych. Strona internetowa, która wyświetla dynamicznie generowaną odpowiedź – np. pobiera dane z bazy danych – może mieć wyższy czas TTFB niż statyczna strona internetowa, którą można wyświetlić od razu bez znacznego czasu obliczeniowego na backendzie. Wyświetlanie wskaźnika wczytywania, a następnie pobieranie wszystkich danych po stronie klienta przenosi wysiłek z bardziej przewidywalnego środowiska po stronie serwera do potencjalnie nieprzewidywalnego środowiska po stronie klienta. Minimalizowanie wysiłku po stronie klienta zwykle poprawia wskaźniki zorientowane na użytkownika.

Jeśli użytkownicy doświadczają wolnego TTFB w terenie, możesz udostępnić informacje o tym, gdzie na serwerze upłynął czas, za pomocą Server-Timingnagłówka odpowiedzi:

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

Wartość nagłówka Server-Timing może zawierać wiele danych, a także czas trwania każdego z nich. Dane te można następnie zbierać od użytkowników w terenie za pomocą interfejsu Navigation Timing API i analizować, aby sprawdzić, czy użytkownicy doświadczają opóźnień. W poprzednim fragmencie kodu nagłówek odpowiedzi zawiera 2 czasy:

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

Możesz też sprawdzić infrastrukturę hostingu i upewnić się, że masz wystarczające zasoby do obsługi ruchu w witrynie. Dostawcy hostingu współdzielonego często mają wysoki TTFB, a dedykowane rozwiązania zapewniające krótszy czas odpowiedzi mogą być droższe.

Kompresja

Odpowiedzi tekstowe, takie jak HTML, JavaScript, CSS i obrazy SVG, powinny być kompresowane, aby zmniejszyć ich rozmiar przesyłany przez sieć i umożliwić szybsze pobieranie. Najczęściej używane algorytmy kompresji to gzip i Brotli. Brotli zapewnia poprawę o około 15–20% w porównaniu z gzip.

Kompresja jest często konfigurowana automatycznie przez większość dostawców hostingu WWW, ale jeśli masz możliwość samodzielnego skonfigurowania lub dostosowania ustawień kompresji, warto wziąć pod uwagę kilka ważnych kwestii:

  1. W miarę możliwości używaj Brotli. Jak już wspomnieliśmy, Brotli zapewnia dość zauważalną poprawę w porównaniu z gzip, a Brotli jest obsługiwany we wszystkich głównych przeglądarkach. W miarę możliwości używaj Brotli, ale jeśli Twoja witryna jest używana przez wielu użytkowników starszych przeglądarek, upewnij się, że w razie potrzeby używana jest kompresja gzip, ponieważ każda kompresja jest lepsza niż jej brak.
  2. Rozmiar pliku ma znaczenie. Bardzo małe zasoby (poniżej 1 KiB) nie podlegają kompresji lub podlegają jej w niewielkim stopniu. Skuteczność każdego typu kompresji danych zależy od dużej ilości danych, z którymi algorytm kompresji może pracować, aby znaleźć bardziej podatne na kompresję bity danych. Im większy plik, tym lepsza kompresja. Nie wysyłaj jednak bardzo dużych zasobów tylko dlatego, że można je skuteczniej skompresować. Duże zasoby, takie jak JavaScript i CSS, wymagają znacznie więcej czasu na przeanalizowanie i ocenę po tym, jak przeglądarka je rozpakuje. Mogą też częściej ulegać zmianom, nawet jeśli są one niewielkie, ponieważ każda zmiana powoduje powstanie innego skrótu pliku.
  3. Poznaj różnicę między kompresją dynamiczną a statyczną. Kompresja dynamiczna i statyczna to różne podejścia do tego, kiedy zasób powinien być skompresowany. Kompresja dynamiczna kompresuje zasób w momencie, gdy jest on żądany, a czasami za każdym razem, gdy jest on żądany. Z drugiej strony kompresja statyczna kompresuje pliki z wyprzedzeniem, więc w momencie żądania nie trzeba przeprowadzać kompresji. Kompresja statyczna eliminuje opóźnienie związane z samą kompresją, które w przypadku kompresji dynamicznej może wydłużać czas odpowiedzi serwera. Zasoby statyczne, takie jak JavaScript, CSS i obrazy SVG, powinny być kompresowane statycznie, natomiast zasoby HTML – zwłaszcza jeśli są generowane dynamicznie dla uwierzytelnionych użytkowników – powinny być kompresowane dynamicznie.

Samodzielne prawidłowe skonfigurowanie kompresji jest trudne, dlatego często najlepiej jest powierzyć to zadanie sieci dostarczania treści (CDN), o której piszemy w następnej sekcji. Znajomość tych pojęć może jednak pomóc Ci określić, czy Twój dostawca hostingu prawidłowo stosuje kompresję. Ta wiedza może pomóc Ci znaleźć możliwości ulepszenia ustawień kompresji, aby przynosiły one maksymalne korzyści dla Twojej witryny.

Sieci dostarczania treści (CDN)

Sieć dostarczania treści (CDN) to rozproszona sieć serwerów, która buforuje zasoby z serwera pierwotnego, a następnie udostępnia je z serwerów brzegowych znajdujących się bliżej użytkowników. Bliskość fizyczna użytkowników skraca czas podróży w obie strony (RTT), a optymalizacje takie jak HTTP/2 lub HTTP/3, buforowanie i kompresja umożliwiają CDN szybsze dostarczanie treści niż w przypadku pobierania ich z serwera źródłowego. Korzystanie z CDN może w niektórych przypadkach znacznie skrócić czas TTFB witryny.

Sprawdź swoją wiedzę

Jakiego typu przekierowanie jest całkowicie pod Twoją kontrolą?

Przekierowanie między domenami.
Przekierowanie w tej samej domenie.

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

Fałsz
Prawda

Który typ serwera jest prawdopodobnie fizycznie najbliżej użytkowników końcowych?

serwery brzegowe sieci dostarczania treści (CDN);
serwer pochodzenia Twojej witryny;

Dalej: zrozumienie ścieżki krytycznej

Teraz, gdy znasz już niektóre kwestie związane z wydajnością, które dotyczą kodu HTML Twojej witryny, możesz zadbać o to, aby wczytywała się ona jak najszybciej. To jednak dopiero początek nauki o wydajności witryn. Następnie omówimy teorię ścieżki krytycznego renderowania. W tym module opisujemy kluczowe pojęcia, takie jak zasoby blokujące renderowanie i parsowanie, oraz ich rolę w jak najszybszym renderowaniu strony w przeglądarce.