Szybsze wczytywanie stron dzięki funkcji wczesnych podpowiedzi z serwera

Dowiedz się, jak serwer może wysyłać do przeglądarki wskazówki dotyczące krytycznych zasobów podrzędnych.

Czym są wczesne wskazówki?

Z czasem witryny stały się bardziej złożone. W związku z tym nie jest niczym niezwykłym, że serwer musi wykonać niełatwą pracę (na przykład uzyskać dostęp do baz danych lub sieci CDN uzyskujące dostęp do serwera pierwotnego), aby wygenerować kod HTML żądanej strony. Niestety taki „czas na myśli serwera” powoduje dodatkowe opóźnienie, zanim przeglądarka zacznie renderować stronę. W rzeczywistości połączenie jest w rzeczywistości bezczynne tak długo, jak długo serwer przygotowuje odpowiedź.

Obraz pokazujący odstęp czasowy między załadowaniem strony a załadowaniem innych zasobów przez serwer wynoszący 200 ms.
Bez wczesnych wskazówek: wszystko jest zablokowane na serwerze, który decyduje o tym, jak zareagować w przypadku głównego zasobu.

Wczesne wskazówki to kod stanu HTTP (103 Early Hints) używany do wysyłania wstępnej odpowiedzi HTTP przed ostateczną odpowiedzią. Dzięki temu serwer może wysyłać do przeglądarki wskazówki dotyczące krytycznych zasobów podrzędnych (np. arkuszy stylów na stronie, krytyczny kod JavaScript) lub źródeł, które prawdopodobnie będą używane przez stronę, gdy serwer jest zajęty generowaniem zasobu głównego. Przeglądarka może wykorzystać te wskazówki, aby rozgrzewać połączenia i żądać zasobów podrzędnych podczas oczekiwania na zasób główny. Innymi słowy, funkcja Early Hints pomaga przeglądarce wykorzystać „czas na przemyślenie serwera” przez wykonywanie pewnych działań z wyprzedzeniem, co przyspiesza wczytywanie strony.

Obraz pokazujący, jak funkcja Wczesne wskazówki umożliwia stronie wysyłanie odpowiedzi częściowej.
Za pomocą wczesnych wskazówek: serwer może wyświetlić odpowiedź częściową ze wskazówkami dotyczącymi zasobów, podczas gdy sam określa ostateczną odpowiedź.

W niektórych przypadkach poprawa skuteczności największego wyrenderowania treści może trwać nawet kilkaset milisekund (jak obserwują w Shopify i Cloudflare, a nawet o sekundę, jak widać w porównaniu przed i po:

Porównanie dwóch witryn.
Porównanie wczesnych wskazówek w witrynie testowej za pomocą WebPageTest (Moto G4 – DSL)

Jak korzystać z wczesnych wskazówek

Aby zacząć korzystać z wczesnych wskazówek, należy zidentyfikować najskuteczniejsze strony docelowe, czyli te, na które zwykle użytkownicy trafiają po odwiedzeniu Twojej witryny. Może to być strona główna lub strona z popularnymi informacjami o produktach, jeśli wielu użytkowników odwiedza inne witryny. Te punkty wejścia mają większe znaczenie niż inne strony, ponieważ przydatność wczesnych wskazówek maleje w miarę, jak użytkownik porusza się po Twojej witrynie (tzn. przeglądarka może mieć wszystkie potrzebne zasoby podrzędne przy drugiej lub trzeciej kolejnej nawigacji). Warto też zrobić dobre pierwsze wrażenie.

Gdy masz już listę stron docelowych z priorytetami, kolejnym krokiem jest określenie, które źródła lub zasoby podrzędne będą dobrym uzupełnieniem wskazówek preconnect lub preload. Zazwyczaj są to źródła i zasoby podrzędne, które mają największy wpływ na kluczowe dane o użytkownikach, takie jak Największe wyrenderowanie treści czy Pierwsze wyrenderowanie treści. Mówiąc dokładniej, poszukaj zasobów podrzędnych blokujących renderowanie, takich jak synchroniczny kod JavaScript, arkusze stylów, a nawet czcionki internetowe. Analogicznie szukaj źródeł zawierających zasoby podrzędne, które w dużym stopniu wpływają na kluczowe dane o użytkownikach.

Pamiętaj też, że jeśli Twoje główne zasoby korzystają już z preconnect lub preload, możesz wziąć pod uwagę te źródła lub zasoby wśród kandydatów do wczesnych wskazówek. Więcej informacji znajdziesz w artykule o optymalizacji LCP. Jednak naiwne kopiowanie dyrektyw preconnect i preload z HTML do wczesnych wskazówek może nie być optymalne.

Podczas używania ich w kodzie HTML lepiej jest zwykle preconnect lub preload zasobów, których skaner wstępnego wczytywania nie wykryje w kodzie HTML. Są to na przykład czcionki czy obrazy tła, które w innym przypadku zostałyby wykryte późno. W przypadku wczesnych wskazówek nie masz kodu HTML, dlatego lepiej jest zamiast niego preconnect kierować do najważniejszych domen lub preload zasobów o krytycznym znaczeniu, które być może zostałyby wykryte na wczesnym etapie kodu HTML – na przykład przez wstępne wczytywanie main.css lub app.js.Poza tym nie wszystkie przeglądarki obsługują wczesne wskazówki (preload) – zapoznaj się z Pomocą dla przeglądarek.

Drugi krok polega na zminimalizowaniu ryzyka stosowania wczesnych wskazówek w przypadku zasobów lub źródeł, które mogą być nieaktualne bądź nieużywane przez główny zasób. Na przykład zasoby, które są często aktualizowane i mają różne wersje (np. example.com/css/main.fa231e9c.css), mogą nie być najlepszym wyborem. Pamiętaj, że problem nie dotyczy wczesnych wskazówek. Dotyczy wszystkich funkcji preload lub preconnect, wszędzie tam, gdzie mogą się pojawić. Są to takie szczegóły, które najlepiej sprawdzają się w przypadku automatyzacji i szablonów (np. w wyniku ręcznego przetwarzania zaszyfrowanego adresu URL lub wersji między preload a rzeczywistym tagiem HTML korzystającym z zasobu istnieje większe prawdopodobieństwo, że hasz lub adresy URL wersji różnią się od siebie).

Możesz na przykład wziąć pod uwagę następujący przepływ:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

Serwer przewiduje, że będzie potrzebny dodatek main.abcd100.css, i sugeruje wstępne wczytanie go za pomocą wczesnych wskazówek:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Chwilę później wyświetla się strona internetowa wraz z powiązaną usługą porównywania cen. Ten zasób CSS jest często aktualizowany, a zasób główny jest już o 5 wersji (abcd105) przed prognozowanym zasobem CSS (abcd100).

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

Ogólnie staraj się tworzyć zasoby i pochodzenie, które są dość stabilne i w dużej mierze niezależne od wyników dotyczących głównego zasobu. W razie potrzeby możesz podzielić kluczowe zasoby na 2 części: stabilną przeznaczoną do stosowania ze wczesnymi wskazówkami i bardziej dynamiczną część do pobrania po odebraniu głównego zasobu przez przeglądarkę:

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

Na koniec po stronie serwera poszukaj żądań głównych zasobów wysyłanych przez przeglądarki, które obsługują wczesne wskazówki, i natychmiast odpowiedz z informacjami o pierwszych krokach. W odpowiedzi 103 uwzględnij odpowiednie wskazówki dotyczące wstępnego połączenia i wstępnego wczytywania. Gdy główny zasób będzie gotowy, użyj zwykłej odpowiedzi (na przykład 200 OK, jeśli operacja się uda). Aby zapewnić zgodność wsteczną, warto też umieścić w końcowej odpowiedzi nagłówki HTTP Link, a nawet uzupełnić zasoby kluczowe, które najwyraźniej są widoczne podczas generowania zasobu głównego (na przykład dynamicznej części klucza zasobu w przypadku skorzystania z sugestii „podziel na 2”). Jak to wygląda:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

Kilka chwil później:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

Obsługiwane przeglądarki

Chociaż wskazówki 103 wczesnych wskazówek są obsługiwane przez wszystkie popularne przeglądarki, instrukcje dostępne we wczesnej ramach różnią się w zależności od przeglądarki:

Obsługa wstępnego połączenia:

Obsługa przeglądarek

  • 103
  • 103
  • 120
  • 17

Obsługa wstępnego wczytywania:

Obsługa przeglądarek

  • 103
  • 103
  • 123
  • x

Narzędzia deweloperskie w Chrome mają też obsługę 103 wcześniejszych wskazówek, a nagłówki Link można zobaczyć w zasobach dokumentu:

Panel sieci przedstawiający nagłówki wczesnych wskazówek
Nagłówki wczesnych wskazówek Link są wyświetlane w Narzędziach deweloperskich w Chrome.

Uwaga: aby korzystać z zasobów wczesnych wskazówek, w Narzędziach deweloperskich nie można zaznaczać opcji Disable cache, ponieważ ta funkcja korzysta z pamięci podręcznej przeglądarki. W przypadku wstępnie załadowanych zasobów inicjator będzie wyświetlany jako early-hints, a size – jako (Disk cache):

Panel sieci przedstawiający inicjatory wczesnych wskazówek
Zasoby z wcześniejszymi podpowiedziami mają inicjator early-hints i są wczytywane z pamięci podręcznej dysku.

Wymaga to też zaufanego certyfikatu do testowania HTTPS.

Firefox (wersja 126) nie ma wyraźnej obsługi 103 wskazówek w Narzędziach deweloperskich, ale zasoby wczytywane z użyciem wczesnych wskazówek nie pokazują informacji o nagłówku HTTP, co jest jednym z wskaźników, że zostały załadowane za pomocą wczesnych wskazówek.

Obsługa serwerów

Oto krótkie podsumowanie poziomu obsługi wczesnych wskazówek w popularnym oprogramowaniu serwerowym HTTP typu open source:

Łatwiejsze włączanie wczesnych wskazówek

Jeśli używasz jednej z tych sieci CDN lub platform, być może nie musisz ręcznie implementować wczesnych wskazówek. Aby dowiedzieć się, czy dostawca rozwiązania obsługuje wczesne wskazówki, zapoznaj się z dokumentacją online dostawcy Twojego rozwiązania. Możesz też zajrzeć na tę niepełną listę:

Jak uniknąć problemów w przypadku klientów, którzy nie obsługują funkcji wczesnego etapu

Informacyjne odpowiedzi HTTP z zakresu 100 są częścią standardu HTTP, ale niektóre starsze klienty lub boty mogą mieć z nimi problemy, ponieważ przed wprowadzeniem „103 wczesnych wskazówek” były one rzadko używane do ogólnego przeglądania internetu.

Wysyłanie tylko 103 wczesnych wskazówek w odpowiedzi na klienty wysyłające nagłówek żądania HTTP sec-fetch-mode: navigate powinno zapewniać wysyłanie takich wskazówek tylko do nowszych klientów, którzy rozumieją, że mogą czekać na kolejną odpowiedź. Poza tym wczesne wskazówki są obsługiwane tylko w przypadku żądań nawigacji (patrz bieżące ograniczenia), więc ma dodatkową zaletę uniknięcia niepotrzebnego wysyłania ich w przypadku innych żądań.

Dodatkowo zaleca się, aby wczesne wskazówki były wysyłane tylko przez połączenia HTTP/2 lub HTTP/3 – większość przeglądarek akceptuje je jedynie w przypadku tych protokołów.

Wzór zaawansowany

Jeśli po zastosowaniu wczesnej wersji w przypadku kluczowych stron docelowych szukasz nowych możliwości, może Cię zainteresować poniższy zaawansowany wzorzec.

W przypadku użytkowników, którzy w ramach typowej ścieżki użytkownika otrzymują nth żądanie strony, możesz dostosować odpowiedź z wczesnymi wskazówkami do treści, które pojawiają się niżej i w dalszych częściach strony. Inaczej mówiąc, w przypadku zasobów o niższym priorytecie skorzystaj z wczesnych wskazówek. Może to wydawać się sprzeczne z intuicją, ponieważ zalecamy skupienie się na zasobach podrzędnych lub źródłach o wysokim priorytecie, które blokują renderowanie. Jednak po upływie pewnego czasu od przeglądania witryny przez użytkownika najprawdopodobniej jego przeglądarka ma już wszystkie niezbędne zasoby. Następnie może warto rozważyć wykorzystanie zasobów o niższym priorytecie. Może to na przykład oznaczać korzystanie ze wczesnych wskazówek w celu wczytywania zdjęć produktów lub używanie dodatkowych plików JS/CSS, które są potrzebne tylko w przypadku rzadziej spotykanych użytkowników.

Obecne ograniczenia

Oto ograniczenia wczesnych wskazówek zaimplementowanych w Chrome:

  • Dostępne tylko w przypadku żądań nawigacji (czyli głównego zasobu dokumentu najwyższego poziomu).
  • Obsługuje tylko preconnect i preload (czyli prefetch nie jest obsługiwany).
  • Wcześniejsze wskazówki, po których następuje przekierowanie z innych domen, powodują, że Chrome usuwa zasoby i połączenia uzyskane za pomocą wczesnych wskazówek.
  • Zasoby wstępnie wczytywane za pomocą wczesnych wskazówek są przechowywane w pamięci podręcznej HTTP i później pobierane stamtąd przez stronę. Dlatego za pomocą wczesnych wskazówek można wstępnie załadować tylko zasoby możliwe do buforowania. W przeciwnym razie zasób zostanie dwukrotnie pobrany (raz przez wczesną podpowiedź, a potem przez dokument). W Chrome pamięć podręczna HTTP jest wyłączona w przypadku niezaufanych certyfikatów HTTPS (nawet jeśli przystąpisz do wczytywania strony).

Inne przeglądarki mają podobne ograniczenia, a jak wspomnieliśmy wcześniej, niektóre 103 wczesne wskazówki dotyczą tylko przeglądarki preconnect.

Co dalej?

W zależności od zainteresowania społeczności możemy rozszerzyć wdrażanie wczesnych wskazówek o następujące funkcje:

  • Wczesne wskazówki dotyczące zasobów, których nie można przechowywać w pamięci podręcznej, korzystających z pamięci podręcznej zamiast z pamięci podręcznej HTTP.
  • Wczesne wskazówki dotyczące żądań zasobów podrzędnych.
  • Wczesne wskazówki wysyłane dotyczące żądań głównego zasobu iframe.
  • Obsługa pobierania z wyprzedzeniem we wczesnych podpowiedziach.

Chętnie poznamy Twoją opinię na temat tego, które aspekty należy traktować priorytetowo oraz jak możemy ulepszyć wczesną pomoc.

Relacja z H2/Push

Jeśli znasz wycofaną funkcję HTTP2/Push, możesz się zastanawiać, czym różni się funkcja Wczesne wskazówki. Wczesne wskazówki wymagają przesyłania w obie strony, aby przeglądarka mogła pobierać kluczowe zasoby podrzędne, natomiast przy HTTP2/Push serwer może zacząć przekazywać zasoby podrzędne wraz z odpowiedzią. Choć brzmiało to niesamowicie, doprowadziło do wielkiego wady strukturalnej: wprowadzenie protokołu HTTP2/Push było niezwykle trudne, aby uniknąć przekazywania zasobów podrzędnych, które przeglądarka już miała. Ten efekt „nadmiernego ruchu” skutkował mniejszym wykorzystaniem przepustowości sieci, co znacznie obniżyło wydajność. Ogólnie dane Chrome pokazały, że protokół HTTP2/Push miały negatywny wpływ na wydajność w internecie.

Z kolei funkcja Early Hints jest bardziej skuteczna w praktyce, ponieważ łączy możliwość wysłania wstępnej odpowiedzi z podpowiedziami, dzięki którym przeglądarka może pozyskiwać informacje, czyli łączyć się z tym, czego rzeczywiście potrzebuje. Chociaż wskazówki Early Hints nie obejmują wszystkich przypadków użycia, które teoretycznie mogłyby rozwiązać za pomocą protokołu HTTP2/Push, uważamy, że wskazówki Early Hints są bardziej praktycznym rozwiązaniem, które przyspiesza nawigację.

Miniatura: Pierre Bamin.