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

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 znajdować oraz pobierać zasoby, takie jak obrazy, skrypty czy kod CSS, przypisuje im atrybut priority pobierania, który umożliwia ich pobranie w optymalnej kolejności. Priorytet zasobu w dokumencie zwykle zależy od jego rodzaju i miejsca. Na przykład obrazy widoczne w widocznym obszarze mogą mieć priorytet High, a w kodzie CSS wczytywanym blokującym renderowanie <link>są priorytety <head>Very High. Automatyczne przypisywanie priorytetów sprawdza się zwykle dobrze, ale w niektórych przypadkach zdarza się, że przypisana kolejność nie jest optymalna.

Na tej stronie omawiamy interfejs Fetch Priority API i atrybut HTML fetchpriority, które pomagają zoptymalizować podstawowe wskaźniki internetowe dzięki wskazówkom dotyczącym względnego priorytetu zasobu (high lub low).

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 używanych później w celu lepszej kolejności 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 wstępnego łączenia. Wstępne wczytywanie pozwala poinformować przeglądarkę o kluczowych zasobach, które chcesz załadować na wczesnym etapie, zanim przeglądarka je w sposób naturalny 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 za pomocą 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. Wybierz obraz największego wyrenderowania treści, który po wczytaniu nadal będzie miał niski priorytet. Jeśli zostanie ona odsunięta przez inne zasoby o niskim priorytecie, użycie priorytetu pobierania może pomóc w szybkim wczytaniu 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.
  • Wskazówka dotycząca zasobu preload, która pomaga przeglądarce szybciej wykryć zasób i załadować go wcześniej.
  • Zmiana priorytetu obliczania skryptów w skryptach async lub defer.

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 z tym samym obliczonym priorytetem w kolejności, w jakiej są wykrywane. 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ę priorytetu, klikając nagłówki tabeli prawym przyciskiem myszy.

Zrzut ekranu z zasobami wymienionymi na karcie Sieć w Narzędziach deweloperskich w Chrome W kolejnych od lewej do prawej widoczne są informacje w kolumnach: nazwa, stan, typ, inicjator, rozmiar, czas i priorytet.
Priorytet zasobu type = "font" na stronie z informacjami o wiadomościach BBC
Zrzut ekranu z zasobami wymienionymi na karcie Sieć w Narzędziach deweloperskich w Chrome W kolejnych od lewej do prawej widoczne są informacje w kolumnach: nazwa, stan, typ, inicjator, rozmiar, czas i priorytet.
Priorytet typu zasobu = „script” na stronie z informacjami o wiadomościach BBC.

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

Zrzut ekranu z zasobami wymienionymi na karcie 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 elementów, które można zmienić bez użycia priorytetu pobierania:

  • Umieść tagi zasobów takie jak <script> i <link> w kolejności, w jakiej mają być pobierane przez przeglądarkę.
  • Skorzystaj ze wskazówki dotyczącej zasobów preload, aby pobrać niezbędne zasoby wcześniej, zwłaszcza te, które przeglądarka trudniej wykryć.
  • Używaj async lub defer, aby pobierać skrypty bez blokowania innych zasobów.
  • Leniwe ładowanie treści w części strony widocznej na ekranie, dzięki czemu przeglądarka może wykorzystać dostępną przepustowość na potrzeby bardziej newralgicznych zasobów w części strony widocznej na ekranie.

Oto bardziej złożone przypadki, w których priorytet pobierania może pomóc w ustaleniu kolejności tych zasobów:

  • 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.
  • Obrazy powitalne w widocznym obszarze zwykle mają priorytet Low lub Medium. Po utworzeniu układu Chrome odkrywa, że znajdują się w widocznym obszarze, i zwiększa ich priorytet. Powoduje to zwykle znaczne opóźnienie wczytywania obrazów. Dzięki określeniu priorytetu pobierania w znacznikach obraz będzie miał priorytet „Wysoki” i będzie się szybciej ładować.

    Wstępne wczytywanie jest wciąż 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, dodaj element fetchpriority='high' podczas wstępnego wczytywania.
  • Zadeklarowanie skryptów jako async lub defer informuje przeglądarkę, że ma je asynchronicznie wczytywać. 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 JavaScript fetch() API, przeglądarka przypisuje mu priorytet High. Niektóre pobierania mogą być uruchamiane z niższym priorytetem, zwłaszcza jeśli łączysz wywołania interfejsu API w tle 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 przypisuje element CSS i czcionki obiektowi High" priority, ale niektóre z tych zasobów mogą być ważniejsze niż inne. Priorytet pobierania pozwala obniżyć priorytet zasobów niekrytycznych.

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 wysoki priorytet i chcesz, aby przeglądarka nadawała mu priorytet, o ile algorytm heurystyczny tego nie zabrania.
  • low: zasób ma niski priorytet i chcesz, by przeglądarka obniżała jego priorytet, jeśli pozwala na to heurystyka.
  • auto: wartość domyślna, która pozwala przeglądarce wybrać odpowiedni priorytet.

Oto kilka przykładów użycia atrybutu fetchpriority w znacznikach oraz właściwości priority odpowiadającej zapisowi skryptu.

<!-- 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.

  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 „VeryHigh”/„Highest”, a użycie w tych elementach fetchpriority="low" – „High”. Żaden z tych przypadków nie obejmuje wyraźnego ustawienia priorytetu na High lub Low.

Przykłady zastosowań

Użyj atrybutu fetchpriority, jeśli chcesz przekazać 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 wczytanym z ustawieniem priorytetu pobierania i bez niego. Przy ustawionym 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. 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>

We wcześniejszym eksperymencie z aplikacją Oodle korzystaliśmy z tej opcji, aby obniżyć priorytet obrazów, które nie wyświetlają się po wczytaniu. Czas wczytywania strony został skrócony 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 do pierwszego obrazu karuzeli umożliwia szybsze wczytywanie strony.

Obniż priorytet wstępnie wczytywanych zasobów

Aby zapobiec konkurowaniu wstępnie wczytywanych zasobów 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" href="/js/script.js" as="script" fetchpriority="low">

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

Zmień priorytet skryptów

Skrypty na Twojej stronie muszą być interaktywne, ale muszą szybko się ładować, ale nie powinny blokować innych zasobów. 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ą uruchomione później na stronie, możesz je załadować z niższym priorytetem:

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

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

Oto kilka kwestii, o których należy pamiętać podczas korzystania z priorytetu pobierania:

  • Atrybut fetchpriority jest wskazówką, a nie dyrektywą. Przeglądarka próbuje uwzględnić preferencje 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. Z kolei priorytet pobierania nie poprawia wykrywalności, ale pozwala zwiększyć lub zmniejszyć priorytet pobierania.
    • Łatwiej 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 priorytetów. Jeśli jako jeden z pierwszych elementów w pliku <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 obraz o znaczeniu krytycznym jest obrazem tła w CSS, załaduj 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. Zdarza się to zwykle w przypadku połączeń HTTP/1.x, w których pobieranie równoległe nie jest możliwe, lub połączeń HTTP/2 o niskiej przepustowości. W takich przypadkach ustalanie priorytetów może pomóc w rozwiązaniu wąskich gardeł.

  • Sieci CDN nie implementują priorytetyzacji HTTP/2 równomiernie. 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 przy użyciu protokołów obsługujących określanie priorytetów (HTTP/2 i HTTP/3). Warto go jednak używać tylko do wewnętrznego określania priorytetów przeglądarki niezależnie od obsługi CDN i źródeł, ponieważ priorytety często zmieniają się, gdy przeglądarka wysyła żądanie 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ątku projektu może nie być możliwe. Na późniejszym etapie programowania możesz przypisać priorytety do różnych zasobów na stronie. Jeśli nie odpowiadają Twoim oczekiwaniom, możesz wprowadzić priorytet pobierania w celu dalszej optymalizacji.

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 oznacza to, że wstępnie wczytuje dane w kolejności, w której parser dokonuje wczytania danych powyżej „średniego”. Uważaj, jeśli używasz wstępnego wczytywania na początku kodu HTML.
  • Wstępne wczytywanie czcionek działa najlepiej na końcu nagłówka lub na początku treści.
  • Importy wstępne (dynamiczne import() lub modulepreload) powinny być uruchamiane po tagu skryptu, który wymaga importu, dlatego najpierw upewnij się, że skrypt został wczytany lub przetworzony, aby można go było ocenić w trakcie wczytywania zależności.
  • Wstępne wczytywanie obrazów mają domyślnie priorytet „Niski” lub „Średni”. Ustaw kolejność w stosunku do 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 nazywano to wskazówkami priorytetowymi. Od tego czasu interfejs został zmieniony na fetchpriority w języku HTML i na priority w przypadku interfejsu JavaScript Download API w ramach procesu związanego ze standardami internetowymi. Aby uniknąć nieporozumień, wywołujemy teraz ten priorytet pobierania przez interfejs API.