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 kluczowych zasobów podrzędnych.

Co to są wczesne wskazówki?

Strony internetowe stają się z czasem coraz bardziej zaawansowane. 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ę. Połączenie jest nieaktywne przez cały czas, jaki serwer potrzebuje na przygotowanie odpowiedzi.

Obraz pokazujący przerwę w czasie przetwarzania na serwerze wynoszącą 200 ms między wczytaniem strony a wczytaniem innych zasobów.
Bez wczesnych wskazówek: na serwerze wszystko jest zablokowane, co określa, jaką odpowiedź ma zwrócić główny zasób.

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 kluczowych zasobów podrzędnych (np. arkuszy stylów strony czy kluczowego kodu JavaScript) lub źródeł, których prawdopodobnie użyje strona, podczas gdy serwer generuje zasób główny. Podczas oczekiwania na główny zasób przeglądarka może używać tych wskazówek do rozgrzewania połączeń i wysyłania żądań dotyczących podzasobów. Innymi słowy, wczesne wskazówki pomagają przeglądarce korzystać z tego „czasu na przemyślenie” na serwerze, wykonując część pracy z wyprzedzeniem, co przyspiesza wczytywanie stron.

Obraz pokazujący, jak wczesne wskazówki umożliwiają stronie wysł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 wydajności największego wyrenderowania treści może wynosić od kilkuset milisekund (jak w przypadku ShopifyCloudflare) do nawet sekundy (jak widać na tym porównaniu przed i po):

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

Jak korzystać z wczesnych wskazówek

Pierwszym krokiem do korzystania z wcześniejszych wskazówek jest określenie najważniejszych stron docelowych, czyli stron, od których użytkownicy zwykle zaczynają przeglądanie Twojej witryny. Może to być strona główna lub strona popularnych produktów, jeśli masz wielu użytkowników z innych witryn. Te punkty wejścia są ważniejsze niż inne strony, ponieważ użyteczność wczesnych podpowiedzi maleje wraz z przemieszczaniem się użytkownika po witrynie (czyli przeglądarka ma większe szanse na to, że będzie mieć wszystkie potrzebne zasoby podrzędne podczas drugiego lub trzeciego przejścia). Warto też zadbać o dobre pierwsze wrażenie.

Po utworzeniu uporządkowanej listy stron docelowych należy określić, które źródła lub podzasoby nadają się do stosowania 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. Podobnie szukaj źródeł, które zawierają podzasoby, które w znaczącym stopniu wpływają na kluczowe dane o użytkownikach.

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

Zazwyczaj używa się ich w HTML, aby preconnect lub preload zasobów, których skaner wstępnego ładowania nie wykryje w HTML, np. czcionek lub obrazów tła, które w przeciwnym razie zostaną wykryte zbyt późno. W przypadku wczesnych podpowiedzi nie masz kodu HTML, więc możesz zamiast tego preconnect do domen lub preload kluczowych zasobów, które mogą zostać wykryte we wczesnej części kodu HTML, np. do wstępnego wczytania main.css lub app.js. Ponadto nie wszystkie przeglądarki obsługują preload w przypadku wczesnych podpowiedzi (patrz Obsługa w przeglądarkach).

Drugi krok polega na minimalizowaniu ryzyka użycia wczesnych wskazówek w przypadku zasobów lub źródeł, które mogą być nieaktualne lub nieużywane przez zasób główny. 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 ta kwestia nie dotyczy tylko wczesnych wskazówek, ale wszystkie elementy preload lub preconnect, niezależnie od tego, gdzie się znajdują. Takie szczegóły najlepiej przetwarzać automatycznie lub za pomocą szablonów (np. ręczny proces spowoduje, że adresy URL haszy lub wersji w preload i rzeczywistym tagu HTML używającym zasobu mogą się nie zgadzać).

Oto przykładowy 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 do przodu (abcd105) w stosunku do przewidywanego zasobu CSS (abcd100).

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

Ogólnie staraj się wybierać zasoby i źródła, które są dość stabilne i w dużej mierze niezależne od wyniku głównego zasobu. W razie potrzeby możesz podzielić kluczowe zasoby na 2 części: stabilną część przeznaczoną do korzystania z wczesnych wskazówek i bardziej dynamiczną część, która będzie pobierana po otrzymaniu 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 za pomocą 103 wczesnych wskazówek. W odpowiedzi na żądanie 103 podaj odpowiednie wskazówki dotyczące wstępnego połączenia i wstępnego wczytania. Gdy główny zasób będzie gotowy, prześlij zwykłą odpowiedź (np. 200 OK w przypadku pomyślnego wykonania). 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 zastosowania 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

Po chwili:

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ługa przeglądarek

Chociaż lista 103 wskazówek jest dostępna we wszystkich popularnych przeglądarkach, 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

  • Chrome: 103.
  • Edge: 103.
  • Firefox: 120.
  • Safari: 17.

Wsparcie dotyczące wstępnego wczytywania:

Obsługa przeglądarek

  • Chrome: 103.
  • Edge: 103.
  • Firefox: 123.
  • Safari: nieobsługiwane.

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 sieciowy z nagłówkami wczesnych wskazówek
Nagłówki Link Wczesna sugestia 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ć pola Disable cache, ponieważ ta funkcja korzysta z pamięci podręcznej przeglądarki. W przypadku załadowanych wcześniej zasobów inicjator będzie widoczny jako early-hints, a rozmiar jako (Disk cache):

Panel sieciowy z informacjami o inicjatorach wczesnych podpowiedzi
Zasoby z wcześniejszymi podpowiedziami mają inicjator early-hints i są wczytywane z pamięci podręcznej dysku.

Wymaga to również zaufanego certyfikatu na potrzeby testowania HTTPS.

Firefox (od wersji 126) nie obsługuje w DevTools wyraźnie wczesnych podpowiedzi 103, ale zasoby wczytywane za pomocą wczesnych podpowiedzi nie zawierają informacji o nagłówku HTTP, co jest jednym z wskaźników, że zostały one wczytane za pomocą wczesnych podpowiedzi.

Obsługa serwerów

Oto krótkie podsumowanie poziomu obsługi wczesnych podpowiedzi w popularnym oprogramowaniu open source serwera HTTP:

Włączanie wczesnych podpowiedzi w prostszy sposób

Jeśli korzystasz z jednego z tych CDN-ów lub platform, 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 lub przejrzyj tę niepełną listę:

Jak uniknąć problemów w przypadku klientów, którzy nie obsługują wczesnych podpowiedzi

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 podpowiedzi wczesnej 103 tylko w odpowiedzi na żądanie klienta, które zawiera nagłówek HTTP sec-fetch-mode: navigate, powinno zapewnić, że takie podpowiedzi są wysyłane tylko do nowszych klientów, którzy rozumieją, że muszą czekać na kolejną odpowiedź. Poza tym wczesne wskazówki są obsługiwane tylko w przypadku żądań nawigacji (patrz bieżące ograniczenia), dlatego ma to dodatkową korzyść w postaci uniknięcia niepotrzebnego wysyłania ich w przypadku innych żądań.

Ponadto wczesne wskazówki powinny być wysyłane tylko przez połączenia HTTP/2 lub HTTP/3, a większość przeglądarek akceptuje je tylko w ramach tych protokołów.

Wzór zaawansowany

Jeśli w pełni zastosowałeś wstępne wskazówki na najważniejszych stronach docelowych i szukasz nowych możliwości, możesz zainteresować się tym zaawansowanym wzorcem.

W przypadku użytkowników, którzy otrzymują n. żądanie strony w ramach typowej ścieżki użytkownika, 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, możesz skorzystać z wczesnych wskazówek dotyczących zasobów o niższym priorytecie. 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 gdy użytkownik już trochę pokieruje, przeglądarka prawdopodobnie będzie już miała wszystkie najważniejsze zasoby. Wtedy warto zająć się zasobami o mniejszym priorytecie. Może to na przykład oznaczać użycie wczesnych podpowiedzi do wczytywania zdjęć produktów lub dodatkowego kodu JS/CSS, który jest potrzebny tylko do rzadszych interakcji użytkownika.

Obecne ograniczenia

Oto ograniczenia wczesnej obsługi zapytań 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).
  • Wczesne wskazówki, po których następuje przekierowanie między domenami w ostatecznej odpowiedzi, spowodują, że Chrome odrzuci zasoby i połączenia uzyskane za pomocą wczesnych wskazówek.
  • Zasoby wstępnie wczytane za pomocą wczesnych wskazówek są przechowywane w pamięci podręcznej HTTP i później pobierane z niej przez stronę. Dlatego za pomocą wczesnych wskazówek można wstępnie wczytywać tylko zasoby, które można zapisać w pamięci podręcznej. W przeciwnym razie zasób zostanie dwukrotnie pobrany (raz przez wczesną podpowiedź, a potem ponownie przez dokument). W Chrome pamięć podręczna HTTP jest wyłączona w przypadku niesprawdzonych certyfikatów HTTPS (nawet jeśli wczytasz stronę).
  • Wstępne wczytywanie obrazów dostosowanych (za pomocą tagów imagesrcset, imagesizes lub media) nie jest obsługiwane za pomocą nagłówków HTTP <link>, ponieważ widoczny obszar nie jest zdefiniowany, dopóki nie zostanie utworzony dokument. Oznacza to, że nie można używać wskazówek wczesnego wyświetlania do wstępnego wczytania obrazów elastycznych, ponieważ może to spowodować załadowanie nieprawidłowego obrazu. Zapoznaj się z tą dyskusją na temat propozycji, jak lepiej sobie z tym radzić.

Inne przeglądarki mają podobne ograniczenia, a jak już wspomnieliśmy, niektóre z nich ograniczają wyświetlanie wskazówek wczesnych 103 do tylko preconnect.

Co dalej?

W zależności od zainteresowania społeczności możemy rozszerzyć implementację wczesnych podpowiedzi o te funkcje:

  • Wczesne wskazówki dotyczące zasobów, których nie można przechowywać w pamięci podręcznej, z użyciem pamięci podręcznej zamiast pamięci podręcznej HTTP.
  • Wczesne wskazówki wysyłane w przypadku żądań dotyczących zasobów podrzędnych.
  • Wczesne wskazówki wysyłane w przypadku żądań głównych zasobów iframe.
  • Obsługa wstępnego pobierania w ramach wczesnych podpowiedzi.

Czekamy na Twoje opinie na temat tego, które aspekty powinny być priorytetowe i jak można jeszcze udoskonalić Wczesne wskazówki.

Związek z H2/Push

Jeśli znasz wycofaną funkcję HTTP2/Push, możesz się zastanawiać, czym różnią się wczesne wskazówki. Wczesne wskazówki wymagają od przeglądarki dwukierunkowej komunikacji, aby mogła zacząć pobierać kluczowe podresury, ale w przypadku HTTP2/Push serwer może zacząć przesyłać podresury wraz z odpowiedzią. Chociaż brzmi to niesamowicie, miało to jedną poważną wadę strukturalną: w przypadku HTTP2/Push bardzo trudno było uniknąć przesyłania 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 z Chrome pokazały, że HTTP2/Push w ogóle nie wpływa na wydajność w internecie.

W praktyce wczesna wskazówka działa lepiej, ponieważ łączy możliwość wysłania wstępnej odpowiedzi ze wskazówkami, które pozwalają przeglądarce samodzielnie pobierać lub łączyć się z tym, czego potrzebuje. Chociaż wczesne wskazówki nie obejmują wszystkich przypadków użycia, które teoretycznie obsługuje HTTP2/Push, uważamy, że wczesne wskazówki to bardziej praktyczne rozwiązanie do przyspieszania nawigacji.

Miniatura autorstwa Pierre Bamin.