Zoptymalizuj wczytywanie zasobów za pomocą interfejsu Fetch Priority API

Interfejs Fetch Priority API wskazuje względny priorytet zasobów względem przeglądarki. Może umożliwić optymalne wczytywanie i ulepszanie podstawowych wskaźników internetowych.

Addy Osmani
Addy Osmani
Leena Sohoni
Leena Sohoni
Patrick Meenan
Patrick Meenan

Obsługa przeglądarek

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 132.
  • Safari: 17.2.

Źródło

Gdy przeglądarka analizuje stronę internetową i zaczyna wykrywać oraz pobierać zasoby, takie jak obrazy, skrypty czy CSS, przypisuje jej pobranie priority, aby pobrać je w optymalnej kolejności. Priorytet zasobu zależy zwykle od tego, czym jest i gdzie znajduje się w dokumencie. Na przykład priorytet obrazów w widocznym obszarze może wynosić High, a priorytetu wczesnego wczytywania, blokującego renderowanie CSS, który korzysta z elementów <link> w elemencie <head>, może być Very High. Przeglądarki dość dobrze przypisują priorytety, które działają dobrze, ale nie zawsze są optymalne.

Ta strona zawiera informacje o interfejsie Fetch Priority API i atrybut HTML fetchpriority, który pozwala określić względny priorytet zasobu (high lub low). Priorytet pobierania może pomóc w optymalizacji podstawowych wskaźników internetowych.

Podsumowanie

Kilka kluczowych obszarów, w których funkcja Pobieranie z wyższym priorytetem może Ci pomóc:

  • Zwiększenie priorytetu obrazu LCP przez określenie w elemencie obrazu fetchpriority="high", co powoduje szybsze wystąpienie LCP.
  • Zwiększenie priorytetu skryptów async, które używają lepszej semantyki niż obecnie najpopularniejszy hack (wstawianie <link rel="preload"> w miejscu skryptu async).
  • Zmniejszenie priorytetu skryptów wykonywanych w później fazie ładowania strony, aby umożliwić lepsze uporządkowanie kolejności wczytywania obrazów.
Widok paska zdjęć z porównaniem 2 testów strony głównej Lotów Google. U dołu pole „Fetch Priority” (Priorytet pobierania) zwiększa priorytet obrazu banera powitalnego, co przekłada się na spadek LCP o 0, 7 sekundy.
Fetch Priority skrócił czas Largest Contentful Paint z 2,6 s do 1,9 s w teście Lotów Google.

Wcześniej deweloperzy mieli ograniczony wpływ na priorytet zasobów przy użyciu funkcji preloadpreconnect. Wstępne wczytywanie umożliwia poinformowanie przeglądarki o kluczowych zasobach, które mają zostać wczytane wcześniej, zanim przeglądarka je wykryje. Jest to szczególnie przydatne w przypadku zasobów, które są trudniejsze do znalezienia, takich jak czcionki umieszczone w arkuszach stylów, obrazy tła lub zasoby wczytywane ze skryptu. Preconnect pomaga rozgrzewać połączenia z serwerami z innych domen i pomaga ulepszać wskaźniki takie jak Czas do pierwszego bajtu. Jest to przydatne, gdy znasz źródło, ale niekoniecznie dokładny adres URL zasobu, który będzie potrzebny.

Priorytet pobierania uzupełnia te wskazówki dotyczące zasobów. Jest to sygnał oparty na znacznikach, dostępny za pomocą atrybutu fetchpriority, którego deweloperzy mogą używać do wskazywania względnego priorytetu danego zasobu. Możesz też korzystać z tych wskazówek w języku JavaScript oraz za pomocą interfejsu Fetch API z właściwością priority, by wpływać na priorytet pobierania zasobów dla danych. Priorytet pobierania może również uzupełniać wstępne wczytywanie. Weź pod uwagę obraz największego wyrenderowania treści, który po wstępnym załadowaniu nadal będzie miał niski priorytet. Jeśli jest przesuwany przez inne zasoby o niskim priorytecie, użycie opcji Pobierz z priorytetem może przyspieszyć wczytywanie obrazu.

Priorytet zasobu

Sekwencja pobierania zasobów zależy od priorytetu przypisanego przez przeglądarkę do każdego zasobu na stronie. Czynniki, które mogą wpływać na logikę obliczania priorytetów:

  • Typ zasobu, np. CSS, czcionki, skrypty, obrazy i zasoby zewnętrzne.
  • Lokalizacja lub kolejność, w której dokument odwołuje się do zasobów.
  • Określa, czy w skryptach są używane atrybuty async lub defer.

W tabeli poniżej pokazujemy, jak Chrome nadaje priorytet większości zasobów i porządkuje je w sekwencje:

  Ładowanie w etapu blokowania układu Wczytywanie pojedynczo w fazie blokowania układu
Blink
Priorytet
Bardzo wysoki Wysoki Średnie Niski Bardzo niski
Narzędzia deweloperskie
Priorytet
Najwyższa Wysoki Średnie Niski Najniższa
Główny zasób
CSS (wczesny etap**) CSS (spóźniony**) CSS (niezgodność multimediów***)
Skrypt (przed czasem** lub nie ze skanera wstępnego wczytywania) Skrypt (spóźnione**) Skrypt (asynchroniczny)
Czcionka czcionka (rel=preload);
Importuj
Obraz (w widocznym obszarze) Obraz (5 pierwszych obrazów > 10 000 pikseli) Obraz
Multimedia (wideo/audio)
Pobieranie z wyprzedzeniem
XSL
XHR (synchronizacja) XHR/pobieranie* (asynchroniczne)

Przeglądarka pobiera zasoby o tym samym obliczonym priorytecie w kolejności ich wykrywania. Priorytet przypisany do różnych zasobów możesz sprawdzić podczas wczytywania strony na karcie Sieć w Narzędziach deweloperskich w Chrome. (Pamiętaj, aby uwzględnić kolumnę priorytet. Aby to zrobić, kliknij prawym przyciskiem myszy nagłówki tabeli i zaznacz tę opcję).

Karta Sieć w Narzędziach deweloperskich w Chrome z listą zasobów czcionek. Wszystkie mają najwyższy priorytet.
Priorytet zasobu type = "font" na stronie szczegółów wiadomości BBC
Karta Sieć w Narzędziach deweloperskich w Chrome z listą zasobów czcionek. Są to zarówno zadania o niskim, jak i wysokim priorytecie.
Priorytet zasobu type = "script" na stronie szczegółów wiadomości BBC.

Gdy priorytety się zmieniają, możesz zobaczyć zarówno początkowy, jak i ostateczny priorytet w ustawieniu Wiersze dużych żądań lub w etykietce.

Karta Sieć w Narzędziach deweloperskich w Chrome. Zaznaczone jest ustawienie „Big request rows”, a kolumna Priorytet pokazuje pierwsze zdjęcie z priorytetem wysokim i innym niższym priorytetem niższym niż wysoki. To samo jest wyświetlane w etykietce.
Zmiana priorytetów w Narzędziach deweloperskich.

Kiedy możesz potrzebować priorytetu pobierania?

Teraz, gdy już znasz logikę ustalania priorytetów przez przeglądarkę, możesz zmienić kolejność pobierania stron, aby zoptymalizować ich wydajność i Podstawowe wskaźniki internetowe. Oto kilka przykładów rzeczy, które możesz zmienić, aby wpływać na priorytet pobierania zasobów:

  • Umieść tagi zasobów, takie jak <script><link>, w takim porządku, w jakim przeglądarka ma je pobrać. Zasoby o tym samym priorytecie są zwykle ładowane w kolejności, w jakiej zostały znalezione.
  • Użyj wskazówki dotyczącej zasobu preload, aby wcześniej pobrać niezbędne zasoby, zwłaszcza te, które trudno jest przeglądarce szybko znaleźć.
  • Aby pobrać skrypty bez blokowania innych zasobów, użyj komponentu async lub defer.
  • Leniwe ładowanie treści w części strony widocznej po przewinięciu, dzięki czemu przeglądarka może korzystać z dostępnej przepustowości w przypadku ważniejszych zasobów, które znajdują się w części strony widocznej na ekranie.

Te techniki pomagają kontrolować sposób obliczania priorytetów przeglądarki, co przekłada się na poprawę wydajności i podstawowych wskaźników internetowych. Na przykład gdy kluczowy obraz tła jest wstępnie wczytywany, może zostać znaleziony znacznie wcześniej, co poprawia wynik największego wyrenderowania treści (LCP).

Czasami te nicki mogą nie wystarczyć, aby zoptymalizować zasoby pod kątem aplikacji. Oto kilka scenariuszy, w których priorytet pobierania może być przydatny:

  • Masz kilka obrazów w części strony widocznej na ekranie, ale nie wszystkie powinny mieć ten sam priorytet. Na przykład w karuzeli obrazów tylko pierwszy widoczny obraz potrzebuje wyższego priorytetu, a pozostałe, zwykle poza ekranem, najpierw można nadać niższy priorytet.
  • Obrazy w widocznym obszarze zazwyczaj mają priorytet Low. Po ukończeniu układu Chrome wykrywa, że strona znajduje się w widocznym obszarze, i zwiększa ich priorytet. Powoduje to zwykle znaczne opóźnienie wczytywania krytycznych obrazów, takich jak obrazy banera powitalnego. Podanie priorytetu pobierania w znacznikach sprawia, że obraz zaczyna się wczytywać z priorytetem High i wczytuje się znacznie wcześniej. Aby to nieco zautomatyzować, Chrome ustawi priorytet Medium dla pierwszych 5 dużych obrazów, co w tym pomoże, ale wartość „fetchpriority="high"” będzie jeszcze lepsza.

    Wstępne wczytywanie jest nadal wymagane do wczesnego wykrywania obrazów LCP uwzględnionych jako tła CSS. Aby zwiększyć priorytet obrazów tła, dodaj do wstępnego wczytywania fetchpriority='high'.
  • Oznaczenie skryptów jako async lub defer powoduje, że przeglądarka wczytuje je asynchronicznie. Jednak jak widać w tabeli priorytetów, tym skryptom również przypisano priorytet „Niski”. Możesz zwiększyć ich priorytet, zapewniając jednocześnie asynchroniczne pobieranie, zwłaszcza w przypadku skryptów, które są kluczowe dla wygody użytkowników.
  • Jeśli do asynchronicznego pobierania zasobów lub danych używasz interfejsu JavaScript fetch() API, przeglądarka nadaje mu priorytet High. Niektóre pobierania mogą być wykonywane z mniejszym priorytetem, zwłaszcza jeśli mieszasz wywołania interfejsu API w tle z wywołaniami interfejsu API, które reagują na dane wejściowe użytkownika. Priorytetom wywołań interfejsu API w tle ustaw priorytet Low, a interaktywnych wywołań interfejsu API – priorytet High.
  • Przeglądarka przypisuje stylesheetom i fontom priorytet High, ale niektóre z tych zasobów mogą być ważniejsze od innych. Możesz użyć opcji Priorytet pobierania, aby obniżyć priorytet niekrytycznych zasobów (pamiętaj, że wczesny kod CSS blokuje renderowanie, więc jego priorytet powinien mieć zwykle priorytet High).

Atrybut fetchpriority

Użyj atrybutu HTML fetchpriority, aby określić priorytet pobierania dla typów zasobów takich jak CSS, czcionki, skrypty i obrazy pobrane za pomocą tagów link, img lub script. Może przyjmować następujące wartości:

  • high: zasób ma wyższy priorytet i chcesz, aby przeglądarka przypisała mu wyższy priorytet niż zwykle, o ile tylko nie przeszkadza w tym heurystyka przeglądarki.
  • low: zasób ma niższy priorytet i chcesz, by przeglądarka obniżyła jego priorytet, jeśli zezwalają na to ustawienia heurystyczne.
  • auto: wartość domyślna, która pozwala przeglądarce wybrać odpowiedni priorytet.

Oto kilka przykładów użycia atrybutu fetchpriority w znacznikach oraz jego odpowiednika w kodzie skryptu, czyli właściwości priority.

<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">

<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">

<script>
  fetch('https://example.com/', {priority: 'low'})
  .then(data => {
    // Trigger a low priority fetch
  });
</script>

Wpływ priorytetu przeglądarki i fetchpriority

Aby zwiększyć lub zmniejszyć obliczony priorytet zasobów, możesz zastosować atrybut fetchpriority do różnych zasobów, jak pokazano w tabeli poniżej. fetchpriority="auto" (◉) w każdym wierszu oznacza domyślny priorytet dla danego typu zasobu. (dostępny też jako Dokument Google).

  Ładowanie w etapu blokowania układu Ładowanie po jednym w fazie blokowania układu
Blink
Priorytet
Bardzo wysoki Wysoki Średnie Niski Bardzo niski
Narzędzia deweloperskie
Priorytet
Najwyższa Wysoki Średnie Niski Najniższa
Główny zasób
CSS (wczesna**) ⬆◉
CSS (spóźniony**)
CSS (niezgodna treść mediów***) ⬆*** ◉⬇
Skrypt (przed czasem** lub nie ze skanera wstępnego wczytywania) ⬆◉
Skrypt (spóźnione**)
Skrypt (asynchroniczny/odroczony) ◉⬇
Czcionka
czcionka (rel=preload); ⬆◉
Importuj
Obraz (w widocznym obszarze – po układzie) ⬆◉
Obraz (pierwsze 5 obrazów > 10 tys. pikseli2)
Obraz ◉⬇
Multimedia (wideo/audio)
XHR (synchronizacja) – wycofane
XHR/pobieranie* (asynchroniczne) ⬆◉
Pobieranie z wyprzedzeniem
XSL

fetchpriority ustawia względny priorytet, co oznacza, że podnosi lub obniża domyślny priorytet o odpowiednią wartość, zamiast ustawiać go bezpośrednio na High lub Low. Często daje to priorytet High lub Low, ale nie zawsze. Na przykład krytyczny kod CSS z atrybutem fetchpriority="high" zachowuje priorytet „bardzo wysoki”/„najwyższy”, a użycie elementu fetchpriority="low" w tych elementach zachowuje priorytet „wysoki”. Żaden z tych przypadków nie wymaga jawnego ustawienia priorytetu High ani Low.

Przypadki użycia

Użyj atrybutu fetchpriority, jeśli chcesz przekazać przeglądarce dodatkową wskazówkę dotyczącą priorytetu pobierania zasobu.

Zwiększ priorytet obrazu LCP

Możesz ustawić wartość fetchpriority="high", aby zwiększyć priorytet LCP lub innych kluczowych obrazów.

<img src="lcp-image.jpg" fetchpriority="high">

Poniższe porównanie pokazuje stronę Loty Google z obrazem tła LCP wczytanym z użyciem priorytetu pobierania i bez niego. Po ustawieniu priorytetu LCP poprawił się z 2,6 s do 1,9 s.

Eksperyment przeprowadzony za pomocą procesów roboczych Cloudflare w celu przeredagowania strony Loty w Google za pomocą priorytetu pobierania.

Użyj wartości fetchpriority="low", aby obniżyć priorytet obrazów powyżej zagięcia, które nie są bezpośrednio ważne, np. obrazów poza ekranem w karuzeli obrazów.

<ul class="carousel">
  <img src="img/carousel-1.jpg" fetchpriority="high">
  <img src="img/carousel-2.jpg" fetchpriority="low">
  <img src="img/carousel-3.jpg" fetchpriority="low">
  <img src="img/carousel-4.jpg" fetchpriority="low">
</ul>

Mimo że obrazy 2–4 znajdują się poza widocznym obszarem, można je uznać za „wystarczająco bliskie”, dzięki czemu zostaną zwiększone do high i wczytają się nawet po dodaniu atrybutu load=lazy. Dlatego fetchpriority="low" jest odpowiednim rozwiązaniem.

W jednym z wcześniejszych eksperymentów z aplikacją Oodle wykorzystaliśmy to rozwiązanie, aby obniżyć priorytet obrazów, które nie wyświetlają się po wczytaniu. Skrócił on czas wczytywania strony o 2 sekundy.

Porównanie priorytetu pobierania w ramach karuzeli obrazów w aplikacji Oodle. Po lewej stronie przeglądarka ustawia domyślne priorytety obrazów karuzelowych, ale pobiera i maluje te obrazy o około 2 sekundy wolniej niż w przykładzie po prawej stronie, co nadaje wyższy priorytet tylko pierwszemu obrazowi w karuzeli.
Przypisanie wysokiego priorytetu tylko do pierwszego obrazu w karuzeli pozwala na szybsze wczytywanie strony.

Obniż priorytet wstępnie wczytywanych zasobów

Aby zapobiec konkurowaniu wstępnie załadowanych zasobów z innymi zasobami krytycznymi, możesz zmniejszyć ich priorytet. Użyj tej metody w przypadku obrazów, skryptów i CSS.

<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">

<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">

Zmiana kolejności skryptów

Skrypty, które powinny być interaktywne, powinny szybko się ładować, ale nie powinny blokować innych, ważniejszych zasobów blokujących renderowanie. Możesz oznaczyć te elementy jako async z wysokim priorytetem.

<script src="async_but_important.js" async fetchpriority="high"></script>

Nie możesz oznaczyć skryptu jako async, jeśli wymaga on określonych stanów DOM. Jeśli jednak zostaną uruchomione później na stronie, możesz je załadować z niższym priorytetem:

<script src="blocking_but_unimportant.js" fetchpriority="low"></script>

Parser nadal będzie blokowany, gdy dotrze do tego skryptu, ale pozwoli na przetworzenie treści przed ustaleniem priorytetów.

Jeśli potrzebujesz pełnego DOM-u, możesz użyć atrybutu defer (który jest wykonywany w kolejności po zdarzeniu DOMContentLoaded) lub nawet async na dole strony.

Obniż priorytet pobierania nieistotnych danych.

Przeglądarka wykonuje fetch z wysokim priorytetem. Jeśli masz wiele pobrań, które mogą być uruchamiane jednocześnie, możesz ustawić wysoki priorytet dla ważniejszych pobrań danych, a obniżony priorytet dla mniej ważnych danych.

// Important validation data (high by default)
let authenticate = await fetch('/user');

// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});

Pobieranie notatek dotyczących implementacji priorytetów

Priorytet pobierania może poprawić wydajność w określonych przypadkach użycia, ale należy pamiętać o kilku kwestiach:

  • Atrybut fetchpriority to wskazówka, a nie dyrektywa. Przeglądarka stara się uwzględnić preferencje dewelopera, ale może też zastosować swoje ustawienia priorytetów zasobów, aby rozwiązać konflikty.
  • Nie myl priorytetu pobierania z wstępnym wczytywaniem:

    • Wstępne wczytywanie jest obowiązkowym pobieraniem, a nie wskazówką.
    • Wstępne wczytywanie umożliwia przeglądarce wykrycie zasobu wcześniej, ale pobiera go z domyślnym priorytetem. I odwrotnie, opcja Priorytet pobierania nie pomaga w wykrywalności, ale pozwala zwiększyć lub zmniejszyć priorytet pobierania.
    • Często łatwiej jest obserwować i mierzyć efekty wstępnego wczytywania niż skutki zmiany priorytetu.

    Priorytet pobierania może uzupełniać wstępne załadowania przez zwiększenie szczegółowości określania priorytetów. Jeśli określisz już wstępne wczytywanie jako jeden z pierwszych elementów obrazu LCP w polu <head>, priorytet pobierania high może nie poprawić znacznie LCP. Jeśli jednak wstępne wczytywanie ma miejsce po wczytaniu innych zasobów, priorytet pobierania high może jeszcze bardziej poprawić LCP. Jeśli kluczowy obraz to obraz tła CSS, przeładuj go za pomocą fetchpriority = "high".

  • Skrócenie czasu wczytywania wynikające z ustalania priorytetów sprawdza się lepiej w środowiskach, w których więcej zasobów rywalizuje o dostępną przepustowość sieci. Jest to typowe w przypadku połączeń HTTP/1.x, w przypadku których nie jest możliwe równoległe pobieranie, lub w przypadku połączeń HTTP/2 lub HTTP/3 o niskiej przepustowości. W takich przypadkach określenie priorytetów może pomóc w rozwiązaniu problemu wąskiego gardła.

  • Sieci CDN nie wdrażają priorytetów HTTP/2 w taki sam sposób, podobnie jak w przypadku HTTP/3. Nawet jeśli przeglądarka przekazuje priorytet z Fetch Priority, usługa CDN może nie zmienić priorytetów zasobów w określonej kolejności. Utrudnia to testowanie opcji Fetch Priority (Priorytet pobierania). Priorytety są stosowane zarówno wewnętrznie w przeglądarce, jak i w przypadku protokołów, które obsługują priorytety (HTTP/2 i HTTP/3). Warto jednak użyć atrybutu priorytet pobierania tylko do wewnętrznego ustalania priorytetów w przeglądarce niezależnie od obsługi CDN lub źródła, ponieważ priorytety często się zmieniają, gdy przeglądarka żąda zasobów. Na przykład zasoby o niskim priorytecie, takie jak obrazy, często nie są pobierane, gdy przeglądarka przetwarza ważne elementy <head>.

  • Wprowadzenie opcji Priorytet pobierania jako sprawdzonej metody na początkowym etapie może być niemożliwe. W późniejszym etapie cyklu programowania możesz przypisać priorytety do różnych zasobów na stronie. Jeśli nie spełniają one Twoich oczekiwań, możesz wprowadzić priorytet pobierania w celu dalszej optymalizacji.

Deweloperzy powinni używać wstępnego wczytywania zgodnie z zamierzonym przeznaczeniem, aby wstępnie wczytywać zasoby, których nie wykrył parser (czcionki, importy, obrazy LCP tła). Umiejscowienie podpowiedzi preload ma wpływ na to, kiedy zasób będzie wstępnie wczytywany.

Priorytet pobierania określa sposób pobierania zasobu.

Wskazówki dotyczące korzystania z wstępnego wczytywania

Podczas korzystania z wstępnych wczytywań pamiętaj o tych kwestiach:

  • Włączenie wstępnego wczytania w nagłówkach HTTP powoduje, że jest ono wczytywane przed wszystkimi innymi zasobami.
  • Zazwyczaj wstępny odczyt danych wczytuje się w kolejności, w jakiej parsujący je moduł dociera do nich w przypadku elementów o priorytecie Medium lub wyższym. Uważaj, jeśli na początku pliku HTML uwzględniasz wczytywanie wstępne.
  • Wstępny wczytywanie czcionek najlepiej sprawdza się na końcu nagłówka lub na początku tekstu.
  • Zaimportowane dane wstępne (dynamiczne import() lub modulepreload) powinny być uruchamiane po tagu skryptu, który wymaga importu. Upewnij się, że skrypt zostanie załadowany lub przeanalizowany jako pierwszy, aby można było go ocenić podczas wczytywania jego zależności.
  • Wstępne wczytywanie obrazów ma domyślnie priorytet Low lub Medium. Uporządkuj je według skryptów asynchronicznych oraz innych tagów o niskim lub najniższym priorytecie.

Historia

Priorytet pobierania został po raz pierwszy przetestowany w Chrome w ramach testowania origin w 2018 roku, a potem ponownie w 2021 roku przy użyciu atrybutu importance. Wtedy nazywały się Wskazówki priorytetowe. Interfejs ten został zmieniony na fetchpriority w przypadku kodu HTML i priority dla JavaScriptu Fetch API w ramach procesu standardów internetowych. Aby uniknąć nieporozumień, nazywamy to teraz priorytetem pobierania interfejsu API.

Podsumowanie

Deweloperzy mogą być zainteresowani priorytetem pobierania z poprawkami w zachowaniu dotyczącym wstępnego ładowania oraz ostatnimi zmianami dotyczącymi podstawowych wskaźników internetowych i wskaźnika LCP. Teraz mają do dyspozycji dodatkowe pokrętła, które umożliwiają uzyskanie preferowanej sekwencji wczytywania.