Leniwe ładowanie obrazów na poziomie przeglądarki w internecie

Wbudowane leniwe ładowanie jest już dostępne!

W internecie dostępna jest teraz obsługa leniwego ładowania obrazów na poziomie przeglądarki. Ten film pokazuje prezentację tej funkcji:

Możesz użyć atrybutu loading do leniwego ładowania obrazów bez konieczności pisania niestandardowego kodu leniwego ładowania lub używania osobnej biblioteki JavaScript. Przejdźmy do szczegółów.

Zgodność z przeglądarką

Obsługa przeglądarek

  • 77
  • 79
  • 75
  • 15,4

Przeglądarki, które nie obsługują atrybutu loading, po prostu ignorują go bez efektów ubocznych.

Dlaczego leniwe ładowanie na poziomie przeglądarki?

Według archiwum HTTP obrazy to najczęściej żądane typy zasobów w przypadku większości witryn i zwykle zajmują one większą przepustowość niż jakiekolwiek inne zasoby. Na 90. percentylu witryny wysyłają na komputery i urządzenia mobilne ponad 5 MB obrazów. To dużo zdjęć kotów.

Wcześniej były dostępne 2 sposoby na opóźnienie wczytywania obrazów niewidocznych na ekranie:

Każda z tych opcji może umożliwić programistom dodanie funkcji leniwego ładowania. Wielu programistów tworzy biblioteki zewnętrzne, aby udostępniać abstrakcje, które są jeszcze łatwiejsze w użyciu. Leniwe ładowanie obsługiwane bezpośrednio przez przeglądarkę nie wymaga jednak zewnętrznej biblioteki. Leniwe ładowanie na poziomie przeglądarki zapewnia też, że odroczone ładowanie obrazów działa nawet wtedy, gdy JavaScript jest wyłączony na kliencie.

Atrybut loading

Chrome wczytuje obrazy o różnych priorytetach w zależności od tego, gdzie znajdują się względem widocznego obszaru urządzenia. Obrazy znajdujące się poniżej widocznego obszaru są wczytywane z niższym priorytetem, ale nadal są pobierane podczas wczytywania strony.

Możesz użyć atrybutu loading, aby całkowicie opóźnić wczytywanie obrazów poza ekranem, które są wyświetlane przez przewijanie:

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Oto obsługiwane wartości atrybutu loading:

  • lazy: opóźnia wczytywanie zasobu, dopóki nie osiągnie obliczonej odległości od widocznego obszaru.
  • eager: domyślne zachowanie przeglądarki oznaczające nieuwzględnienie atrybutu oraz oznacza, że obraz jest wczytywany niezależnie od tego, gdzie znajduje się na stronie. Mimo że jest to ustawienie domyślne, warto go wyraźnie ustawić, jeśli narzędzie automatycznie dodaje loading="lazy", gdy nie ma określonej wartości lub gdy linter nie jest wyraźnie ustawiony.

Związek między atrybutem loading a priorytetem pobierania

Wartość eager oznacza po prostu instrukcje wczytywania obrazu w zwykły sposób, bez opóźniania jego dalszego ładowania, jeśli znajduje się on poza ekranem. Nie oznacza, że obraz bez atrybutu loading="eager" jest wczytywany szybciej niż inny obraz.

Przeglądarki ustalają priorytety zasobów na podstawie różnych heurystyki, a atrybut loading informuje tylko o tym, kiedy zasób graficzny znajduje się w kolejce, a nie jak jest w niej priorytetowy. eager sugeruje jedynie, że domyślnie przeglądarki chcą korzystać z kolejek.

Jeśli chcesz zwiększyć priorytet pobierania ważnego obrazu (np. obrazu LCP), użyj opcji Priorytet pobierania z ustawieniem fetchpriority="high".

Pamiętaj, że obraz z atrybutami loading="lazy" i fetchpriority="high" nadal będzie wyświetlany z opóźnieniem, jeśli znajdzie się poza ekranem, oraz będzie pobierany z wysokim priorytetem, gdy znajdzie się w widocznym obszarze. W tym przypadku prawdopodobnie i tak zostanie ona pobrana z wysokim priorytetem, więc ta kombinacja nie jest potrzebna ani używana.

Progi odległości od widocznego obszaru

Wszystkie obrazy w części strony widocznej na ekranie, czyli natychmiast widoczne bez przewijania, wczytują się normalnie. Te, które znajdują się daleko poniżej widocznego obszaru urządzenia, są pobierane tylko wtedy, gdy użytkownik przewija stronę w jego pobliżu.

Implementacja leniwego ładowania w Chromium ma na celu zapewnienie, że obrazy niewyświetlane na ekranie będą wczytywane na tyle wcześnie, by w chwili, gdy użytkownik przewinął stronę, wczytywały się na tyle szybko. Dzięki pobieraniu obrazów w pobliżu na długo zanim staną się widoczne w widocznym obszarze, zwiększamy prawdopodobieństwo, że zostaną one już wczytane, zanim staną się widoczne.

W porównaniu z bibliotekami JavaScriptu leniwego ładowania progi pobierania obrazów, które przewijają się do widoku, mogą być uznane za zachowawcze.

Próg odległości nie jest stały i zmienia się w zależności od kilku czynników:

Domyślne wartości różnych skutecznych typów połączeń znajdziesz w źródle Chromium. Te liczby, a nawet sposób pobierania tylko po osiągnięciu określonej odległości od widocznego obszaru, mogą się zmienić w przyszłości, gdy zespół Chrome ulepsza heurystyki, aby określić, kiedy należy rozpocząć wczytywanie.

Większa oszczędność danych i progi dotyczące odległości od widocznego obszaru

W lipcu 2020 roku wprowadziliśmy istotne ulepszenia w Chrome, aby dostosować progi leniwego ładowania obrazów od widocznego obszaru, aby lepiej spełniały oczekiwania deweloperów.

W przypadku szybkich połączeń (4G) zmniejszyliśmy progi odległości od widocznego obszaru w Chrome z 3000px do 1250px, a w przypadku wolniejszych połączeń (3G lub niższe) – zmieniliśmy próg z 4000px na 2500px. Ta zmiana daje dwa cele:

  • Działanie <img loading=lazy> jest bliższe działaniu bibliotek leniwego ładowania JavaScriptu.
  • Nowe progi odległości od widocznego obszaru nadal pozwalają nam zagwarantować, że obrazy zostaną prawdopodobnie wczytane, gdy użytkownik przewinie do nich ekran.

Poniżej znajdziesz porównanie starych i nowych progów odległości od widocznego obszaru dla jednej z naszych wersji demonstracyjnych szybkiego połączenia (4G):

Stare a nowe progi:

Nowe i ulepszone progi leniwego ładowania obrazów, które zmniejszają progi odległości od widocznego obszaru dla szybkich połączeń z 3000 do 1250 pikseli.

a porównanie nowych progów i LazySizes (popularna biblioteka leniwego ładowania JavaScriptu):

Nowe progi odległości od widocznego obszaru w Chrome wczytujące 90 KB obrazów w porównaniu z wczytywaniem LazySizes o rozmiarze 70 KB przy tych samych warunkach sieciowych

Zależy nam na współpracy ze społecznością ds. standardów internetowych w celu zapewnienia lepszej zgodności z realizacją progów odległości od widocznego obszaru w różnych przeglądarkach.

Zdjęcia powinny zawierać atrybuty wymiarów

Gdy przeglądarka wczytuje obraz, nie rozpoznaje od razu jego wymiarów, chyba że zostaną one wyraźnie określone. Aby przeglądarka mogła zarezerwować wystarczającą ilość miejsca na stronie na obrazy, zalecamy, aby wszystkie tagi <img> zawierały zarówno atrybuty width, jak i height. Jeśli nie podasz wymiarów, mogą wystąpić zmiany układu, które są bardziej zauważalne na stronach, które długo się wczytują.

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Możesz też określić ich wartości bezpośrednio we stylu wbudowanego:

<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">

Sprawdzoną metodą ustawiania wymiarów jest stosowanie tagów <img> niezależnie od tego, czy są one ładowane z opóźnieniem. Leniwe ładowanie może zwiększyć trafność tych reklam. Ustawienie wartości width i height dla obrazów w nowoczesnych przeglądarkach umożliwia również określenie ich wewnętrznego rozmiaru.

W większości przypadków obrazy są leniwie ładowane, jeśli nie określono wymiarów. Jest jednak kilka skrajnych przypadków, o których trzeba pamiętać. Jeśli nie określono wymiarów width i height, wymiary obrazu wynoszą najpierw 0 × 0 pikseli. Jeśli masz galerię takich obrazów, przeglądarka może stwierdzić, że na początku wszystkie mieszczą się w widocznym obszarze, ponieważ nie zajmują praktycznie miejsca i żadne obrazy nie są przesuwane poza ekran. W takim przypadku przeglądarka stwierdza, że wszystkie z nich są widoczne dla użytkownika, i decyduje się wczytać wszystko.

Poza tym określenie wymiarów obrazu zmniejsza ryzyko wystąpienia zmian układu. Jeśli nie możesz podać wymiarów obrazów, leniwe ładowanie ich może być kompromisem pomiędzy oszczędzaniem zasobów sieciowych i potencjalnie większym ryzykiem przesunięcia układu.

Chociaż leniwe ładowanie w Chromium jest stosowane w taki sposób, że obrazy są zwykle wczytywane po ich wyświetleniu, istnieje niewielkie ryzyko, że jeszcze się nie wczytały. W takim przypadku brak atrybutów width i height na takich obrazach zwiększa ich wpływ na skumulowane przesunięcie układu.

Obrazy zdefiniowane za pomocą elementu <picture> można też ładować leniwie:

<picture>
  <source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
  <img src="photo.jpg" loading="lazy">
</picture>

Mimo że to przeglądarka decyduje, który obraz wczytać z dowolnego elementu <source>, atrybut loading wystarczy, że znajdzie się w zastępczym elemencie <img>.

Unikaj leniwego ładowania obrazów, które znajdują się w pierwszym widocznym obszarze

Należy unikać ustawiania loading=lazy w przypadku obrazów, które znajdują się w pierwszym widocznym widocznym obszarze. Jest to szczególnie istotne w przypadku obrazów LCP. Więcej informacji znajdziesz w artykule Wpływ na wydajność nadmiernego leniwego ładowania.

Zalecamy dodawanie atrybutu loading=lazy tylko do obrazów, które znajdują się w części strony widocznej po przewinięciu, jeśli to możliwe. Obrazy wczytane z łatwością można pobrać od razu, natomiast obrazy ładowane leniwie działają dopiero wtedy, gdy przeglądarka ustali, gdzie na stronie znajduje się obraz, a dostęp do niego zależy od komponentu IntersectionObserver.

Ogólnie wszystkie obrazy w widocznym obszarze powinny być szybko wczytywane za pomocą ustawień domyślnych przeglądarki. Nie musisz określać atrybutu loading=eager, aby tak było w przypadku obrazów widocznych w widocznym obszarze.

<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">

<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">

Płynne pogorszenie

Przeglądarki, które nie obsługują atrybutu loading, zignorują jego obecność. Te przeglądarki oczywiście nie będą korzystać z zalet leniwego ładowania, ale ten atrybut nie ma na nich negatywnego wpływu.

Najczęstsze pytania

Czy planujecie automatyczne leniwe ładowanie obrazów w Chrome?

Wcześniej Chromium automatycznie ładować leniwie wszystkie obrazy, które nadaje się do odroczenia po włączeniu wersji uproszczonej w Chrome na Androida, a atrybut loading nie został podany lub ustawiono na wartość loading="auto". Jednak wersja uproszczona została wycofana (tak jak niestandardowa wersja loading="auto") i obecnie nie planujemy automatycznego leniwego ładowania obrazów w Chrome.

Czy mogę zmienić odległość, w jakiej musi się znajdować obraz, aby został wczytany?

Wartości te są zakodowane na stałe i nie można ich zmienić za pomocą interfejsu API. W przyszłości mogą się jednak zmieniać, ponieważ przeglądarki eksperymentują z różnymi odległościami progowymi i zmiennymi.

Czy obrazy tła w CSS mogą korzystać z atrybutu loading?

Nie. Obecnie można jej używać tylko z tagami <img>.

Czy leniwe ładowanie obrazów, które znajdują się w widocznym obszarze urządzenia, ma jakąś wadę?

Lepiej nie umieszczać metody loading=lazy na obrazach w części strony widocznej na ekranie, ponieważ Chrome nie będzie wstępnie wczytywał obrazów loading=lazy ze skanera wstępnego i opóźnia ich pobieranie do momentu, gdy układ będzie gotowy. Więcej informacji znajdziesz w artykule Unikanie leniwego ładowania obrazów, które znajdują się w pierwszym widocznym obszarze.

Używanie właściwości loading="lazy" może uniemożliwić wczytywanie ich, gdy nie są widoczne, ale znajdują się w obliczonej odległości. Na przykład Chrome, Safari i Firefox nie wczytują obrazów ze stylem display: none;, zarówno w elemencie obrazu, jak i w elemencie nadrzędnym. Inne techniki ukrywania obrazów, np. stosowanie stylu opacity:0, nadal będą jednak powodować ich załadowanie. Zawsze dokładnie testuj implementację, aby mieć pewność, że działa prawidłowo.

Co zrobić, jeśli używam już biblioteki zewnętrznej lub skryptu leniwego ładowania obrazów?

Pełna obsługa natywnego leniwego ładowania jest obecnie dostępna w nowoczesnych przeglądarkach. Może Ci się przydać biblioteka lub skrypt innej firmy do leniwego ładowania obrazów.

Jednym z powodów, dla których warto korzystać z biblioteki zewnętrznej razem z atrybutem loading="lazy", jest udostępnienie kodu polyfill w przeglądarkach, które nie obsługują tego atrybutu, lub zapewnienie większej kontroli nad tym, kiedy jest uruchamiane leniwe ładowanie.

Jak obsłużyć przeglądarki, które nie obsługują leniwego ładowania?

Utwórz kod polyfill lub użyj biblioteki zewnętrznej, aby leniwe ładowanie obrazów w witrynie. Właściwość loading może służyć do wykrywania, czy funkcja jest obsługiwana w przeglądarce:

if ('loading' in HTMLImageElement.prototype) {
  // supported in browser
} else {
  // fetch polyfill/third-party library
}

Na przykład leniwe rozmiary są popularną biblioteką leniwego ładowania JavaScriptu. Możesz wykryć obsługę atrybutu loading, aby wczytać leniwe rozmiary jako bibliotekę zastępczą tylko wtedy, gdy zasada loading nie jest obsługiwana. Działa to w ten sposób:

  • Zamień <img src> na <img data-src>, aby uniknąć nieoczekiwanego ładowania w nieobsługiwanych przeglądarkach. Jeśli atrybut loading jest obsługiwany, zamień wartość data-src na src.
  • Jeśli właściwość loading nie jest obsługiwana, wczytaj kreację zastępczą (leniwe rozmiary) i zainicjuj ją. W dokumentacji leniwego rozmiaru używasz klasy lazyload do wskazywania leniwego rozmiaru obrazów, które mają być ładowane leniwie.
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">

<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">

<script>
  if ('loading' in HTMLImageElement.prototype) {
    const images = document.querySelectorAll('img[loading="lazy"]');
    images.forEach(img => {
      img.src = img.dataset.src;
    });
  } else {
    // Dynamically import the LazySizes library
    const script = document.createElement('script');
    script.src =
      'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
    document.body.appendChild(script);
  }
</script>

Oto prezentacja tego wzorca. Wypróbuj tę funkcję w starszej przeglądarce, aby zobaczyć działanie kreacji zastępczej.

Czy leniwe ładowanie elementów iframe jest też obsługiwane w przeglądarkach?

Obsługa przeglądarek

  • 77
  • 79
  • 121
  • 16.4

Język <iframe loading=lazy> również jest ustandaryzowany i jest już wdrożony w Chromium i Safari. Umożliwia to leniwe ładowanie elementów iframe za pomocą atrybutu loading. Więcej informacji znajdziesz w tym artykule o leniwym ładowaniu elementów iframe.

Jak leniwe ładowanie na poziomie przeglądarki wpływa na reklamy na stronie internetowej?

Wszystkie reklamy wyświetlane użytkownikowi jako obraz lub leniwe ładowanie elementu iframe, tak jak każdy inny obraz lub element iframe.

Jak są obsługiwane obrazy podczas drukowania strony internetowej?

Wszystkie obrazy i elementy iframe są wczytywane natychmiast po wydrukowaniu strony. Szczegółowe informacje znajdziesz w problemie nr 875403.

Czy Lighthouse rozpoznaje leniwe ładowanie na poziomie przeglądarki?

Lighthouse 6.0 i nowsze uwzględniają metody w przypadku leniwego wczytywania obrazów poza ekranem, które mogą korzystać z różnych progów, co pozwala na zaliczenie opóźnienia obrazów poza ekranem.

Podsumowanie

Obsługa leniwego ładowania obrazów może znacznie ułatwić poprawę wydajności stron internetowych.

Czy zauważasz jakieś nietypowe zachowanie po włączeniu tej funkcji w Chrome? Zgłoś błąd