Leniwe ładowanie obrazów

Obrazy mogą pojawiać się na stronie internetowej, jeśli są wbudowane w elementy HTML jako elementy <img> lub jako obrazy tła CSS. Z tego posta dowiesz się, jak leniwie ładować oba typy obrazów.

Obrazy w treści

Najczęściej są to obrazy używane w elementach <img>. W przypadku obrazów w tekście dostępne są 3 opcje leniwego ładowania: Których można używać w połączeniu, aby zapewnić zgodność z różnymi przeglądarkami:

Korzystanie z leniwego ładowania na poziomie przeglądarki

Zarówno Chrome, jak i Firefox obsługują leniwe ładowanie z atrybutem loading. Ten atrybut można dodać do elementów <img> oraz <iframe>. Wartość lazy informuje przeglądarkę, że ma ona wczytać obraz natychmiast, jeśli znajdzie się w widocznym obszarze, i pobierać inne obrazy, gdy użytkownik przewija stronę w pobliżu.

Zobacz pole loading numeru MDN zgodność z przeglądarką w tabeli. Jeśli przeglądarka nie obsługuje leniwego ładowania, atrybut zostanie zignorowany. a obrazy wczytają się od razu, jak zwykle.

W przypadku większości witryn dodanie tego atrybutu do obrazów w tekście pozwala zwiększyć wydajność i oszczędzaj użytkownikom wczytywania obrazów, których być może nigdy nie udało im się przewinąć. Jeśli masz dużą liczbę obrazów i chcesz mieć pewność, że użytkownicy przeglądarek nieobsługujących funkcji leniwego ładowania musisz połączyć tę metodę z jedną z opisanych poniżej metod.

Więcej informacji znajdziesz w artykule o leniwym ładowaniu stron internetowych na poziomie przeglądarki.

Korzystanie z obserwatora skrzyżowania

Do leniwego ładowania elementów <img> używamy kodu JavaScript, by sprawdzić, czy znajdują się one w sekcji widoczny obszar. Jeśli tak, ich atrybuty src (a czasami srcset) są zawiera adresy URL prowadzących do żądanej treści graficznej.

Jeśli masz już za sobą pisanie kodu leniwego ładowania, możliwe, że udało Ci się ukończyć zadanie za pomocą modułów obsługi zdarzeń, takich jak scroll lub resize. Chociaż to podejście jest jest najbardziej kompatybilna z przeglądarkami, jednak nowoczesne przeglądarki zapewniają pozwala sprawdzić widoczność elementów za pomocą metody Intersection Observer API.

Observer Intersection Observer jest łatwiejszy w użyciu i czytelności niż kod oparty na różnych modułów obsługi zdarzeń, bo wystarczy zarejestrować obserwatora, dzięki czemu nie trzeba pisać żmudnego kodu wykrywania widoczności elementów. Wszystkie musisz zdecydować, co zrobić, gdy element będzie widoczny. Przyjmijmy ten podstawowy wzorzec znaczników w elementach <img> ładowanych z leniwym ładowaniem:

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

Oto 3 istotne elementy tego znacznika, na których warto się skupić:

  1. atrybut class, który wybierasz element w JavaScriptu.
  2. Atrybut src, który odwołuje się do obrazu zastępczego, który wyświetli się, gdy po pierwszym wczytaniu strony.
  3. atrybuty data-src i data-srcset, które są atrybutami zastępczymi; zawierający adres URL obrazu, który zostanie wczytany, gdy element znajdzie się w widocznym obszarze.

Zobaczmy teraz, jak za pomocą leniwego ładowania użyć obserwacji intersekcji w JavaScripcie. obrazów używających tego wzorca znaczników:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

W zdarzeniu DOMContentLoaded dokumentu ten skrypt wysyła do DOM zapytania o wszystkie Elementy <img> z klasą lazy. Jeśli obserwacja intersekcji jest dostępna, utwórz nowego obserwatora, który wywołuje wywołanie zwrotne, gdy elementy img.lazy zostaną wprowadzone widoczny obszar.

Intersection Observer (obserwacja skrzyżowań) jest dostępny we wszystkich nowoczesnych przeglądarkach. Dlatego użycie go jako kodu polyfill dla loading="lazy" sprawi, że leniwe ładowanie będzie dostępne dla większości użytkowników.

Obrazy w CSS

Choć tagi <img> są najpopularniejszym sposobem używania obrazów na stronach internetowych, obrazy może być również wywoływane przez CSS background-image (i innych usługach). Leniwe ładowanie na poziomie przeglądarki nie dotyczy obrazów tła CSS. dlatego jeśli masz obrazy tła do leniwego ładowania, musisz rozważyć inne metody.

W odróżnieniu od elementów <img>, które ładują się niezależnie ich widoczności, wczytywanie obrazów w CSS jest do spekulacji. Gdy dokument i obiekt CSS modele i renderowanie drzewo są tworzone, przeglądarka sprawdza, jak kod CSS jest stosowany do dokumentu, zamawianie zasobów zewnętrznych. Jeśli przeglądarka określiła regułę CSS z użyciem zasobu zewnętrznego nie ma zastosowania do dokumentu, ponieważ jest on obecnie nie zostanie utworzony, przeglądarka o nie nie prosi.

To spekulacyjne zachowanie można wykorzystać do opóźnienia wczytywania obrazów w CSS przez używając JavaScriptu, by określić, kiedy element znajduje się w widocznym obszarze. a następnie zastosować do tego elementu klasę, która stosuje styl wywołujący obrazu tła. Dzięki temu obraz jest pobierany w razie potrzeby a nie przy początkowym wczytywaniu. Weźmy na przykład element, który zawiera duży baner powitalny:

<div class="lazy-background">
  <h1>Here's a hero heading to get your attention!</h1>
  <p>Here's hero copy to convince you to buy a thing!</p>
  <a href="/buy-a-thing">Buy a thing!</a>
</div>

Element div.lazy-background normalnie zawiera główne tło który jest wywoływany przez niektóre elementy CSS. W tym przykładzie można wyodrębnić właściwości background-image elementu div.lazy-background za pomocą visible do elementu, który znajduje się w widocznym obszarze:

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

Następnie użyj JavaScriptu, by sprawdzić, czy element znajduje się w widocznym obszarze Observer Intersection!) i dodaj klasę visible do funkcji div.lazy-background, który wczytuje obraz:

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

Wpływ na największe wyrenderowanie treści (LCP)

Leniwe ładowanie to doskonała optymalizacja, która zmniejsza zarówno ogólne wykorzystanie danych, jak i rywalizację między siecią podczas uruchamiania, ponieważ opóźnia ładowanie obrazów do czasu, gdy są potrzebne. Może to skrócić czas uruchamiania i skrócić przetwarzanie w wątku głównym dzięki skróceniu czasu potrzebnego na dekodowanie obrazu.

Leniwe ładowanie to jednak technika, która może negatywnie wpływać na największy LCP wyrenderowania treści w Twojej witrynie, jeśli nie chcesz się nią bawić. Jedną z rzeczy, których należy unikać, jest leniwe ładowanie obrazów, które znajdują się w widocznym obszarze podczas uruchamiania.

W przypadku leniwego ładowania opartego na języku JavaScript należy unikać leniwego ładowania obrazów w widocznym obszarze, ponieważ w tych rozwiązaniach często używa się atrybutu data-src lub data-srcset jako obiektów zastępczych atrybutów src i srcset. Problem polega na tym, że wczytywanie tych obrazów będzie opóźnione, ponieważ skaner wstępnego wczytywania przeglądarki nie może ich znaleźć podczas uruchamiania.

Nawet używanie leniwego ładowania na poziomie przeglądarki w celu leniwego ładowania obrazu w widocznej części ekranu może spowodować błąd. Po zastosowaniu elementu loading="lazy" do obrazu w widocznym obszarze będzie on opóźniony, dopóki przeglądarka nie potwierdzi, że znajduje się w tym obszarze, co może wpłynąć na LCP strony.

Nigdy nie używaj leniwego ładowania obrazów, które są widoczne w widocznym obszarze podczas uruchamiania. To wzorzec, który negatywnie wpływa na LCP witryny i w konsekwencji na wrażenia użytkowników. Jeśli potrzebujesz obrazu przy uruchamianiu, nie ładuj go leniwie, ale jak najszybciej.

Biblioteki z leniwym ładowaniem

Leniwe ładowanie powinno być stosowane zawsze, gdy jest to możliwe, ale jeśli nie ma takiej możliwości (np. znaczna grupa użytkowników nadal korzysta ze starszych przeglądarek), do leniwego ładowania obrazów można użyć tych bibliotek:

  • lazysizes to w pełni funkcjonalna leniwa wersja wczytuje bibliotekę, która leniwie wczytuje obrazy i elementy iframe. Wzór, którego używa on, jest dość podobny do przykładowego kodu pokazanego tutaj, ponieważ automatycznie wiąże się on z lazyload w elementach <img> i wymaga określenia adresów URL obrazów w Atrybuty data-src lub data-srcset, których zawartość jest zastępowana do atrybutów src lub srcset. Wykorzystuje przecięcie Observer (który można wykorzystać polyfill) i można go rozszerzyć za pomocą liczby wtyczek do na przykład leniwego ładowania. Więcej informacji o używaniu leniwych rozmiarów
  • vanilla-lazyload to lekka opcja do leniwego ładowania obrazów, obrazów tła, filmów, elementów iframe i skrypty. Wykorzystuje obserwację intersekcji, obsługuje obrazy elastyczne włącza leniwe ładowanie na poziomie przeglądarki.
  • lozad.js to kolejny nieskomplikowany skrypt która używa tylko obserwacji intersekcji. Dzięki temu jest niezwykle wydajny, ale przed użyciem w starszych przeglądarkach musi zostać wypełniony.
  • Jeśli potrzebujesz biblioteki leniwego ładowania w React, możesz: react-lazyload. Choć nie używa obserwacji skrzyżowań, tylko zapewnia znaną metodę leniwego działania. do wczytywania obrazów osób przyzwyczajonych do tworzenia aplikacji za pomocą React.