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

Interfejs Fetch Priority API wskazuje względny priorytet zasobów dla przeglądarki. Może umożliwić optymalne wczytywanie i poprawić podstawowe wskaźniki internetowe.

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

Obsługa przeglądarek

  • 102
  • 102
  • x
  • 17.2

Źródło

Gdy przeglądarka analizuje stronę internetową i zaczyna odkrywać oraz pobierać zasoby, takie jak obrazy, skrypty czy CSS, przypisuje im atrybut priority pobierania, który umożliwia pobranie ich w optymalnej kolejności. Priorytet zasobu zależy zwykle od tego, co to jest i gdzie w dokumencie. Na przykład obrazy widoczne w widocznym miejscu mogą mieć priorytet High, a priorytet wczesnego wczytywania blokującego renderowanie kodu CSS <link> w tagu <head> może wynosić Very High. Przeglądarki dość dobrze potrafią przypisywać priorytety, które działają poprawnie, ale nie zawsze są optymalne.

Na tej stronie omawiamy interfejs Fetch Priority API i atrybut HTML fetchpriority, który umożliwia wskazanie względnego priorytetu zasobu (high lub low). Priorytet pobierania może pomóc w optymalizacji podstawowych wskaźników internetowych.

Podsumowanie

Oto kilka najważniejszych kwestii, w których może pomóc priorytet pobierania:

  • Zwiększenie priorytetu obrazu LCP przez określenie fetchpriority="high" w elemencie obrazu. Spowoduje to szybsze wywołanie LCP.
  • Zwiększenie priorytetu skryptów async przy użyciu lepszej semantyki niż w przypadku najbardziej typowego ataku (wstawienie <link rel="preload"> do skryptu async).
  • Zmniejszenie priorytetu skryptów z późnej treści w celu lepszej sekwencjonowania obrazów.
Widok paska zdjęć z porównaniem 2 testów strony głównej Lotów Google. U dołu Priorytet pobierania służy do zwiększania priorytetu obrazu banera powitalnego, co powoduje zmniejszenie LCP o 0, 7 sekundy.
Zwiększenie priorytetu pobierania z 2,6 s do 1,9 s w teście Lotów Google.

W przeszłości deweloperzy mieli ograniczony wpływ na priorytet zasobów przy użyciu funkcji wstępnego ładowania i łączenia wstępnego. Wstępne wczytywanie pozwala poinformować przeglądarkę o kluczowych zasobach, które chcesz załadować, zanim przeglądarka w naturalny sposób je wykryje. Jest to szczególnie przydatne w przypadku zasobów, które są trudniejsze do znalezienia, np. czcionek w arkuszach stylów, obrazów tła czy zasobów wczytywanych ze skryptu. Takie połączenie pomaga rozgrzewać połączenia z serwerami z innych domen i poprawia wskaźniki takie jak Czas do pierwszego bajtu. Jest to przydatne, gdy znasz źródło, ale niekoniecznie dokładny adres URL potrzebnego zasobu.

Fetch Priority uzupełnia te wskazówki dotyczące zasobów. Jest to sygnał oparty na znacznikach dostępny w atrybucie fetchpriority, za pomocą którego deweloperzy mogą określać względny priorytet konkretnego zasobu. Możesz też korzystać z tych wskazówek w JavaScript i Fetch API z właściwością priority, aby wpływać na priorytet pobierania zasobów przeznaczonych do danych. Priorytet pobierania może też uzupełniać wstępne wczytywanie. Użyj obrazu największego wyrenderowania treści, który po wstępnie wczytywanym wciąż ma niski priorytet. Jeśli zostanie ona odsunięta przez inne zasoby o niskim priorytecie, użycie priorytetu pobierania może pomóc w szybkim załadowaniu 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ą mieć wpływ na logikę priorytetu, to między innymi:

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

W tabeli poniżej pokazujemy, jak Chrome określa priorytety i sekwencje większości zasobów:

  Wczytywanie na etapie blokowania układu Ładuj pojedynczo na etapie blokowania układu
Mrugnięcie
priorytet
VeryHigh Wysoka Średnie Niska VeryLow
Narzędzia deweloperskie
Priorytet
Najwyższy Wysoka Średnie Niska Najniższa wartość
Główny zasób
CSS (wczesna**) CSS (opóźniony**) CSS (niezgodność multimediów***)
Skrypt (przed czasem** lub ze skanera wstępnego wczytywania) Skrypt (opóźniony**) Skrypt (asynchroniczny)
Czcionka Czcionka (rel=preload)
Importuj
Obraz (w widocznym obszarze) Obraz (pierwsze 5 obrazów > 10 000 pikseli2) Obraz
Multimedia (wideo/dźwięk)
Pobieranie z wyprzedzeniem
Kod XSL
XHR (synchronizacja) XHR/pobieranie* (asynchroniczne)

Przeglądarka pobiera zasoby o tym samym obliczonym priorytecie w kolejności, w jakiej są wykrywane. Priorytety przypisane do różnych zasobów możesz sprawdzić podczas wczytywania strony na karcie Sieć w Narzędziach deweloperskich w Chrome. Pamiętaj, by uwzględnić kolumnę priorytet. Aby to zrobić, kliknij prawym przyciskiem myszy nagłówki tabeli i ją zaznacz.

Karta Network (Sieć) w Narzędziach deweloperskich w Chrome z listą zasobów czcionek. Wszystkie z nich mają najwyższy priorytet.
Priorytet zasobu type = "font" na stronie z informacjami o wiadomościach BBC
Karta Network (Sieć) w Narzędziach deweloperskich w Chrome z listą zasobów czcionek. Są to opcje o wysokim i niskim priorytecie.
Priorytet zasobu type = "script" na stronie z informacjami o wiadomościach BBC.

Gdy priorytety się zmienią, zarówno początkowy, jak i końcowy priorytet będzie widoczny w ustawieniu Wiersze dużych żądań lub w etykietce.

Karta Network (Sieć) w Narzędziach deweloperskich w Chrome. Ustawienie „Big request rows” (Duże wiersze żądania) jest zaznaczone, a w kolumnie Priority (Priorytet) jest wyświetlany pierwszy obraz z priorytetem High (Wysoki) i innym początkowym priorytetem „Medium” (Średni) poniżej. To samo zobaczysz w etykietce.
Zmiany priorytetów w Narzędziach deweloperskich.

Kiedy może być potrzebny priorytet pobierania?

Skoro już wiesz, jak działa ustalanie priorytetów w przeglądarce, możesz dostosować kolejność pobierania strony, aby zoptymalizować jej wydajność oraz podstawowe wskaźniki internetowe. Oto kilka przykładów rzeczy, które możesz zmienić, aby wpłynąć na priorytet pobierania zasobów:

  • Umieść tagi zasobów, takie jak <script> i <link>, w kolejności, w jakiej mają być pobierane przez przeglądarkę. Zasoby o tym samym priorytecie są zwykle ładowane w kolejności, w jakiej są wykrywane.
  • Skorzystaj ze wskazówki dotyczącej zasobów preload, aby wcześniej pobrać niezbędne zasoby, zwłaszcza w przypadku zasobów, które nie są łatwo wykrywane przez przeglądarkę.
  • Używaj async lub defer, aby pobierać skrypty bez blokowania innych zasobów.
  • Leniwe ładowanie treści w części strony widocznej na ekranie pozwala przeglądarce wykorzystać dostępną przepustowość na potrzeby bardziej newralgicznych zasobów w części strony widocznej na ekranie.

Te techniki pomagają kontrolować priorytet przetwarzania danych w przeglądarce, co przekłada się na poprawę wydajności i poprawę podstawowych wskaźników internetowych. Jeśli na przykład wstępnie wczytywany jest krytyczny obraz tła, można go wykryć znacznie wcześniej, co poprawia wskaźnik największego wyrenderowania treści (LCP).

Czasami te nicki mogą nie wystarczyć do określenia optymalnego priorytetu zasobów pod kątem aplikacji. Oto kilka scenariuszy, w których może pomóc priorytet pobierania:

  • Masz kilka obrazów części strony widocznej na ekranie, ale nie wszystkie z nich powinny mieć taki sam priorytet. Na przykład w karuzeli obrazów tylko pierwszy widoczny obraz musi mieć wyższy priorytet, a inne, zwykle poza ekranem, można na początku ustawić na niższy priorytet.
  • Obrazy w widocznym obszarze zwykle mają priorytet Low. Po utworzeniu układu Chrome odkrywa, że znajdują się w widocznym obszarze, i zwiększa ich priorytet. Powoduje to zwykle znaczne opóźnienie w ładowaniu najważniejszych obrazów, takich jak banery powitalne. Jeśli określisz priorytet pobierania w znacznikach, obraz będzie miał na początku priorytet High i będzie się szybciej ładować. Aby nieco to zautomatyzować, Chrome ma ustawiony priorytet Medium dla pierwszych 5 większych obrazów. Jednoznaczny fetchpriority="high" będzie jeszcze lepszy.

    Wstępne wczytywanie jest nadal wymagane, aby można było wczesnego wykrywania obrazów LCP uwzględnionych jako tła CSS. Aby zwiększyć priorytet obrazów tła, podczas wstępnego wczytywania dodaj fetchpriority='high'.
  • Zadeklarowanie skryptów jako async lub defer informuje przeglądarkę, że ma być ładowane asynchronicznie. Jednak jak widać w tabeli priorytetów, te skrypty również mają priorytet „Niski”. Możesz zwiększyć ich priorytet, a jednocześnie zapewnić pobieranie asynchroniczne, zwłaszcza w przypadku skryptów, które mają kluczowe znaczenie dla wygody użytkowników.
  • Jeśli do asynchronicznego pobierania zasobów lub danych używasz interfejsu API JavaScript fetch(), przeglądarka przypisuje mu priorytet High. Niektóre pobierania powinny być uruchamiane z niższym priorytetem, zwłaszcza jeśli łączysz w tle wywołania interfejsu API z wywołaniami interfejsu API, które reagują na dane wejściowe użytkownika. Oznacz wywołania interfejsu API w tle jako priorytet Low, a interaktywne wywołania interfejsu API – priorytet High.
  • Przeglądarka nadaje CSS i czcionki priorytet High, ale niektóre z tych zasobów mogą być ważniejsze niż inne. Priorytet pobierania pozwala obniżyć priorytet zasobów niekrytycznych (pamiętaj, że wczesne renderowanie kodu CSS blokuje renderowanie, więc zwykle powinno mieć 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, jeśli pobierasz je za pomocą tagów link, img lub script. Może przyjmować te wartości:

  • high: zasób ma wyższy priorytet i chcesz, aby przeglądarka nadawała mu wyższy priorytet niż zwykle, o ile nie to blokuje algorytm heurystyczny przeglądarki.
  • low: zasób ma niższy priorytet i chcesz, by przeglądarka obniżała jego priorytet, jeśli pozwala na to heurystyka.
  • auto: wartość domyślna, dzięki której przeglądarka może wybrać odpowiedni priorytet.

Poniżej znajdziesz kilka przykładów użycia atrybutu fetchpriority w znacznikach oraz odpowiadającej mu 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>

Skutki priorytetu przeglądarki i zasady fetchpriority

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

  Wczytywanie na etapie blokowania układu Ładuj pojedynczo na etapie blokowania układu
Mrugnięcie
priorytet
VeryHigh Wysoka Średnie Niska VeryLow
Narzędzia deweloperskie
Priorytet
Najwyższy Wysoka Średnie Niska Najniższa wartość
Główny zasób
CSS (wczesna**) ⬆◉
CSS (opóźniony**)
CSS (niezgodność multimediów***) ⬆*** ◉⬇
Skrypt (przed czasem** lub ze skanera wstępnego wczytywania) ⬆◉
Skrypt (opóźniony**)
Skrypt (asynchroniczny/opóźniony) ◉⬇
Czcionka
Czcionka (rel=preload) ⬆◉
Importuj
Obraz (w widocznym obszarze – po układzie) ⬆◉
Obraz (pierwsze 5 obrazów > 10 000 pikseli2)
Obraz ◉⬇
Multimedia (wideo/dźwięk)
XHR (sync) – wycofane
XHR/pobieranie* (asynchroniczne) ⬆◉
Pobieranie z wyprzedzeniem
Kod XSL

fetchpriority ustawia priorytet względny, co oznacza, że podnosi lub obniża priorytet o odpowiednią wartość, zamiast ustawiać priorytet 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 fetchpriority="low" do tych elementów zachowuje priorytet „Wysoki”. Żaden z tych przypadków nie wymaga wyraźnego ustawienia priorytetu na High lub Low.

Przypadki użycia

Użyj atrybutu fetchpriority, jeśli chcesz dać przeglądarce dodatkową wskazówkę o priorytecie pobierania zasobu.

Zwiększ priorytet obrazu LCP

Możesz użyć ustawienia fetchpriority="high", aby zwiększyć priorytet LCP lub innych obrazów o znaczeniu krytycznym.

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

Porównanie poniżej przedstawia stronę Lotów Google z obrazem tła LCP wczytywanym z priorytetem pobierania i bez niego. Przy ustawionym wysokim priorytecie LCP poprawiło się z 2,6 s do 1,9 s.

Eksperyment przeprowadzony z użyciem pracowników Cloudflare w celu przepisywania strony Lotów Google za pomocą priorytetu pobierania.

Użyj fetchpriority="low", aby obniżyć priorytet obrazów w części strony widocznej na ekranie, które nie są od razu ważne, np. obrazów niewyświetlanych na ekranie 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>

Obrazy 2–4 znajdą się poza widocznym obszarem, ale mogą zostać uznane za „dostatecznie blisko”, aby zwiększyć ich do high i wczytać się nawet po dodaniu atrybutu load=lazy. Dlatego fetchpriority="low" jest odpowiednim rozwiązaniem w tym przypadku.

Podczas wcześniejszego eksperymentu z aplikacją Oodle korzystaliśmy z tej opcji, aby obniżyć priorytet obrazów, które nie wyświetlają się po wczytaniu. Skróciło to czas wczytywania strony o 2 sekundy.

Porównanie priorytetu pobierania w karuzeli obrazów aplikacji Oodle. Po lewej stronie przeglądarka ustawia domyślne priorytety obrazów w karuzeli, ale pobiera i renderuje te obrazy o około 2 sekundy wolniej niż w przykładzie po prawej stronie, przez co wyższy priorytet ma tylko pierwszy obraz w karuzeli.
Użycie wysokiego priorytetu tylko pierwszego obrazu karuzeli umożliwia szybsze wczytywanie strony.

Obniż priorytet wstępnie wczytywanych zasobów

Aby wstępnie wczytane zasoby nie mogły konkurować z innymi zasobami krytycznymi, możesz obniżyć ich priorytet. Wykorzystaj tę technikę w przypadku obrazów, skryptów i kodów 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'">

Zmień priorytet skryptów

Skrypty, które powinna być interaktywna strona, powinny szybko się ładować, ale nie powinny blokować innych, bardziej krytycznych zasobów blokujących renderowanie. Możesz oznaczyć je 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ą wyświetlone później na stronie, możesz je załadować z niższym priorytetem:

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

Spowoduje to zablokowanie parsera po dotarciu do tego skryptu, ale umożliwi nadpisanie priorytetów treściom, które wcześniej do niej dotrą.

Jeśli potrzebny jest gotowy DOM, możesz też użyć atrybutu defer (który uruchamia się w kolejności po DOMContentLoaded) lub nawet async u dołu strony.

Obniż priorytet pobierania danych o znaczeniu niekrytycznym

Przeglądarka wykonuje polecenie fetch z wysokim priorytetem. Jeśli masz wiele pobrań, które mogą być uruchamiane jednocześnie, możesz użyć wysokiego priorytetu pobierania ważniejszych danych, a niższy priorytet danych mniej ważnych.

// 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'});

Pobierz uwagi o implementacji priorytetu pobierania

Priorytet pobierania może zwiększyć wydajność w określonych przypadkach, ale podczas korzystania z tego priorytetu trzeba pamiętać o kilku kwestiach:

  • Atrybut fetchpriority jest wskazówką, a nie dyrektywą. Przeglądarka stara się uwzględnić ustawienie dewelopera, ale może też zastosować preferencje dotyczące priorytetu zasobów w celu rozwiązywania konfliktów.
  • Nie pomyl priorytetu pobierania ze wstępnym wczytywaniem:

    • Wstępne wczytywanie to obowiązkowe pobieranie, a nie wskazówka.
    • Wstępne wczytywanie umożliwia przeglądarce wcześniejsze wykrycie zasobu, ale nadal pobiera zasób z domyślnym priorytetem. I na odwrót – priorytet pobierania nie poprawia wykrywalności, ale pozwala zwiększyć lub zmniejszyć priorytet pobierania.
    • Często łatwiej jest obserwować i mierzyć efekty wstępnego wczytywania niż zmiany priorytetu.

    Priorytet pobierania może uzupełniać wczytywanie wstępne przez zwiększenie szczegółowości określania priorytetów. Jeśli jako jeden z pierwszych elementów w metodzie <head> w przypadku obrazu LCP określono już wstępne wczytywanie, priorytet pobierania high może nie poprawić LCP. Jeśli jednak wstępne wczytywanie ma miejsce po wczytaniu innych zasobów, priorytet pobierania high może jeszcze bardziej zwiększyć LCP. Jeśli krytyczny obraz jest obrazem tła CSS, wczytaj go wstępnie za pomocą atrybutu fetchpriority = "high".

  • Skrócenie czasu ładowania wynikającego z ustalania priorytetów ma większe znaczenie w środowiskach, w których więcej zasobów konkurują o dostępną przepustowość sieci. Jest to częste w przypadku połączeń HTTP/1.x, w przypadku których nie można pobierać równoległego, lub połączeń HTTP/2 lub HTTP/3 o niskiej przepustowości. W takich przypadkach określenie priorytetów może pomóc rozwiązać wąskie gardła.

  • Sieci CDN nie implementują priorytetów HTTP/2 równomiernie i podobnie w przypadku HTTP/3. Nawet jeśli przeglądarka komunikuje priorytet pobierania z priorytetem priorytetu, CDN może nie ustalać priorytetów zasobów w określonej kolejności. Utrudnia to testowanie priorytetu pobierania. Priorytety są stosowane zarówno wewnętrznie w przeglądarce, jak i w protokołach obsługujących określanie priorytetów (HTTP/2 i HTTP/3). Mimo to warto używać tego priorytetu tylko do wewnętrznego określania priorytetów przeglądarki niezależnie od obsługi sieci CDN i punktów początkowych, ponieważ często zmieniają się priorytety, gdy przeglądarka żąda zasobów. Na przykład żądania zasobów o niskim priorytecie, takich jak obrazy, są często wstrzymywane, gdy przeglądarka przetwarza kluczowe elementy <head>.

  • Wprowadzenie priorytetu pobierania jako sprawdzonej metody na początkowym projekcie może nie być możliwe. Na późniejszym etapie programowania możesz przypisać priorytety różnym zasobom na stronie, a jeśli nie odpowiadają Twoim oczekiwaniom, możesz wprowadzić priorytet pobierania w celu dalszej optymalizacji.

Deweloperzy powinni używać funkcji wstępnego wczytywania do zamierzonego celu – do wstępnego wczytywania zasobów, których nie wykrył parser (czcionek, importów, obrazów LCP w tle). Umiejscowienie wskazówki preload będzie miało wpływ na to, kiedy zasób będzie wstępnie wczytywany.

Priorytet pobierania określa sposób pobierania zasobu po jego pobraniu.

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

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

  • Jeśli umieszczasz wstępne wczytywanie w nagłówkach HTTP, elementy są na pierwszym miejscu w kolejności wczytywania.
  • Ogólnie wczytuje się wstępnie w kolejności, w jakiej parser odczytuje wszystkie dane o priorytecie Medium lub wyższym. Uważaj, jeśli stosujesz wstępne wczytywanie na początku kodu HTML.
  • Wstępne wczytywanie czcionek prawdopodobnie najlepiej sprawdza się w części strony głównej lub na początku treści.
  • Importowanie wstępne wczytywania (dynamiczne import() lub modulepreload) powinno się uruchamiać po tagu skryptu, który wymaga importu, dlatego najpierw upewnij się, że skrypt został wczytany lub przeanalizowany, aby można go było sprawdzić w trakcie wczytywania zależności.
  • Wstępne wczytywanie obrazów mają domyślnie priorytet Low lub Medium. Uporządkuj je względem skryptów asynchronicznych i innych tagów o niskim lub najniższym priorytecie.

Historia

Priorytet pobierania po raz pierwszy przetestowaliśmy w Chrome w ramach wersji próbnej origin w 2018 r., a potem ponownie w 2021 r. z użyciem atrybutu importance. Wtedy nazywaliśmy się Wskazówkami priorytetowymi. W tym czasie interfejs został zmieniony na fetchpriority w języku HTML i na priority w przypadku interfejsu JavaScript Fetch API w ramach procesu wdrażania standardów internetowych. Aby uniknąć nieporozumień, wykorzystujemy teraz ten priorytet.

Podsumowanie

Deweloperzy mogą być zainteresowani priorytetem pobierania ze względu na poprawki dotyczące wstępnego wczytywania, a także ostatnio skupione na podstawowych wskaźnikach internetowych i LCP. Dostępne są teraz dodatkowe pokrętła umożliwiające osiągnięcie preferowanej sekwencji wczytywania.