Hybrydowe leniwe ładowanie: progresywna migracja do natywnego leniwego ładowania

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ W sieci pojawia się natywne leniwe ładowanie. Ponieważ nie jest zależny od JavaScript, zrewolucjonizuje sposób, w jaki dzisiaj leniwie ładujemy zawartość, ułatwiając programistom leniwe ładowanie obrazów i ramek iframe. Ale nie jest to funkcja, którą możemy wypełniać wielokrotnie, i minie trochę czasu, zanim stanie się użyteczna we wszystkich przeglądarkach. W tym artykule dowiesz się, jak to działa i jak możesz stopniowo zastępować leniwe ładowanie oparte na JavaScript na jego natywną alternatywę, dzięki hybrydowemu leniwemu ładowaniu.

W ciągu ostatnich kilku tygodni być może słyszałeś lub czytałeś o natywnym leniwym ładowaniu, które pojawi się w Chromium 75 w nadchodzących miesiącach.

„Tak, świetna wiadomość, ale będziemy musieli poczekać, aż wszystkie przeglądarki to obsługują”.

Jeśli to była pierwsza rzecz, która przyszła ci do głowy, czytaj dalej. Postaram się przekonać Cię o czymś przeciwnym.

Zacznijmy od porównania między natywnym leniwym ładowaniem a starym dobrym ładowaniem opartym na JavaScript.

Leniwe ładowanie natywne kontra JavaScript sterowane leniwym ładowaniem

Opóźnione ładowanie to sposób na poprawę wydajności witryny lub aplikacji internetowej poprzez maksymalizację szybkości renderowania obrazów i ramek w części strony widocznej na ekranie oraz elementów iframe (a czasami filmów) poprzez odroczenie ładowania treści w części strony widocznej na ekranie.

Leniwe ładowanie oparte na JavaScript

W celu leniwego ładowania obrazów lub ramek iframe, bardzo powszechną praktyką jest oznaczanie ich przez zastąpienie odpowiedniego atrybutu src podobnym atrybutem danych, data-src , a następnie poleganie na rozwiązaniu JavaScript do wykrywania, kiedy obrazy/iframe są pobierane blisko widocznej części strony (zwykle dlatego, że użytkownik przewinął się w dół) i skopiować atrybuty danych do odpowiednich, a następnie wywołać odroczone ładowanie ich treści.

 <img data-src="turtle.jpg" alt="Lazy turtle" class="lazy">
Więcej po skoku! Kontynuuj czytanie poniżej ↓

Natywne leniwe ładowanie

Zgodnie ze specyfikacją natywnego opóźnionego ładowania (nadal w fazie rozwoju), jeśli chcesz opóźniać ładowanie obrazów lub ramek iframe przy użyciu natywnej funkcji opóźnionego ładowania, wystarczy dodać atrybut loading=lazy do powiązanego tagu.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Addy Osmani obszernie pisał na ten temat w swoim artykule „Native Image Lazy-Loading For The Web!” w którym stwierdził, że zespół Google Chrome już opracowuje tę funkcję i zamierza wprowadzić ją w Chrome 75.

Inne przeglądarki oparte na Chromium, takie jak Opera i Microsoft Edge, również skorzystają z tego rozwoju, zyskując tę ​​samą funkcję w swojej pierwszej aktualizacji opartej na Chromium 75.

Rozpocznij z natywnym leniwym ładowaniem

W przypadku, gdy obrazy Twojej witryny są pobierane jednocześnie podczas lądowania na stronie bez leniwego ładowania, możesz włączyć (jeśli jest to obsługiwane) natywne leniwe ładowanie w swojej witrynie tak łatwo, jak dodanie atrybutu HTML. Atrybut loading informuje przeglądarki, które obrazy są ważne do natychmiastowego załadowania, a które można pobierać leniwie, gdy użytkownicy przewijają w dół. Ten sam atrybut można zastosować do elementów iframe.

Aby poinformować przeglądarki, że określony obraz jest ważny, aby mogły go załadować tak szybko, jak to możliwe, musisz dodać atrybut loading="eager" w tagu img . Najlepszą praktyką jest zrobienie tego dla obrazów głównych — zazwyczaj tych, które będą wyświetlane w części strony widocznej na ekranie.

 <img src="rabbit.jpg" alt="Fast rabbit" loading="eager">

Aby poinformować przeglądarki, że obraz powinien być pobierany leniwie, po prostu dodaj atrybut loading="lazy" . Jest to najlepsza praktyka tylko wtedy, gdy robisz to tylko z obrazami drugorzędnymi — zazwyczaj te będą wyświetlane pod zakładką.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Po prostu dodając atrybut loading do obrazów i ramek iframe, umożliwisz swojej witrynie korzystanie z natywnego leniwego ładowania jako progresywnego ulepszenia. Twoja witryna będzie stopniowo czerpać z tego korzyści, ponieważ wsparcie dociera do użytkowników w większości nowoczesnych przeglądarek.

Jest to najlepsze podejście do zastosowania, jeśli Twoja witryna nie korzysta obecnie z żadnego rodzaju leniwego ładowania, ale jeśli już zaimplementowałeś rozwiązanie z leniwym ładowaniem oparte na JavaScript, możesz chcieć je zachować, stopniowo przełączając się na natywne leniwe ładowanie.

Idealnym rozwiązaniem byłoby natychmiastowe rozpoczęcie korzystania z natywnego leniwego ładowania i użycie wypełniacza, aby działał we wszystkich przeglądarkach. Niestety, natywne leniwe ładowanie nie jest funkcją, którą możemy wypełnić za pomocą JavaScript.

Nie używaj do wypełniacza

Gdy nowa technologia przeglądarki zostanie udostępniona w jednej przeglądarce, społeczność open source zwykle publikuje wypełnienie JavaScript, aby zapewnić tę samą technologię pozostałym przeglądarkom. Na przykład wypełnienie IntersectionObserver wykorzystuje elementy JavaScript i DOM do koordynowania Element.getBoundingClientRect() w celu odtworzenia zachowania natywnego interfejsu API.

Ale przypadek natywnego leniwego ładowania jest inny, ponieważ wypełnienie JavaScript dla load loading="lazy" musiałoby uniemożliwić przeglądarkom ładowanie treści, gdy tylko znajdą adres URL w znaczniku obrazu lub elementu iframe. JavaScript nie ma kontroli nad tym początkowym etapem renderowania strony, dlatego nie jest możliwe ponowne wypełnienie natywnego leniwego ładowania.

Hybrydowe leniwe ładowanie

Jeśli nie jesteś zadowolony z posiadania natywnego lazy loading tylko jako progresywnego ulepszenia lub masz już zaimplementowane lazy loading oparte na JavaScript i nie chcesz stracić tej funkcji w mniej nowoczesnych przeglądarkach (ale nadal chcesz włączyć natywne lazy loading w przeglądarkach które to wspierają), wtedy potrzebujesz innego rozwiązania. Przedstawiamy: hybrydowe leniwe ładowanie.

Hybrydowe leniwe ładowanie to technika używania natywnego leniwego ładowania w przeglądarkach, które je obsługują, w przeciwnym razie polegaj na JavaScript, aby obsłużyć leniwe ładowanie.

Aby wykonać hybrydowe ładowanie z opóźnieniem, musisz oznaczyć swoją leniwą treść za pomocą atrybutów data zamiast rzeczywistych (takich jak w przypadku leniwego ładowania opartego na JavaScript) i dodać atrybut loading="lazy" .

 <img data-src="turtle.jpg" loading="lazy" alt="Lazy turtle">

Następnie potrzebujesz trochę JavaScriptu. Przede wszystkim musisz wykryć, czy przeglądarka obsługuje natywne lazy loading . Następnie wykonaj jedną z poniższych czynności dla każdego elementu z atrybutem loading="lazy" :

  • Jeśli obsługiwane jest natywne ładowanie z opóźnieniem, skopiuj wartość atrybutu data-src do atrybutu src ;
  • Jeśli nie jest to obsługiwane, zainicjuj skrypt lub wtyczkę opóźnionego ładowania JavaScript, aby zrobić to, gdy elementy wejdą do widocznego obszaru.

Samodzielne napisanie kodu JavaScript wymaganego do wykonania tych operacji nie jest trudne. Możesz wykryć, czy natywne ładowanie z opóźnieniem jest obsługiwane przez warunek:

 if ('loading' in HTMLImageElement.prototype)

Jeśli tak, po prostu skopiuj wartość atrybutu src z data-src . Jeśli tak nie jest, zainicjuj wybrany przez siebie skrypt ładujący się z opóźnieniem.

Oto fragment kodu, który to robi.

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <script> (function() { if ("loading" in HTMLImageElement.prototype) { var lazyEls = document.querySelectorAll("[loading=lazy]"); lazyEls.forEach(function(lazyEl) { lazyEl.setAttribute( "src", lazyEl.getAttribute("data-src") ); }); } else { // Dynamically include a lazy loading library of your choice // Here including vanilla-lazyload var script = document.createElement("script"); script.async = true; script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"; window.lazyLoadOptions = { elements_selector: "[loading=lazy]" //eventually more options here }; document.body.appendChild(script); } })(); </script>

Możesz znaleźć i przetestować powyższy kod w tym demo na żywo.

Mimo to jest to bardzo prosty skrypt i sprawy mogą się komplikować, gdy używasz dodatkowych atrybutów lub tagów w celu uzyskania responsywnych obrazów (takich jak srcset i sizes , a nawet tagi picture i source ).

Mała pomoc osób trzecich

Przez ostatnie cztery lata utrzymywałem skrypt leniwego ładowania typu open source o nazwie „ vanilla-lazyload ”, a kilka dni po tym, jak Addy Osmani napisał o natywnym leniwym ładowaniu, społeczność zareagowała, pytając mnie, czy mój skrypt może działać jako wypełniacz.

Jak wyjaśniłem wcześniej, nie można utworzyć wypełniacza dla funkcji natywnego leniwego ładowania, jednak pomyślałem o rozwiązaniu, które ułatwiłoby programistom rozpoczęcie przejścia do natywnego leniwego ładowania, bez konieczności pisania kodu JavaScript, który Wspomniałem wcześniej.

Począwszy od wersji 12 vanilla-lazyload , możesz po prostu ustawić opcję use_native na true aby włączyć hybrydowe ładowanie z opóźnieniem. Skrypt ma tylko 2,0 kB spakowany gzipem i jest już dostępny na GitHub, npm i jsDelivr.

  • Poznaj vanilla-lazyload na GitHub

Prezentacje

Możesz zacząć bawić się z natywnym leniwym ładowaniem już dziś, pobierając Chrome Canary lub Microsoft Edge Insider ( dev channel ), a następnie włączając flagi „Włącz leniwe ładowanie obrazów” i „Włącz leniwe ładowanie ramek”. Aby włączyć te flagi, wpisz about:flags w polu adresu URL przeglądarki i wyszukaj „leniwy” w polu wyszukiwania.

Demo natywnego leniwego ładowania

Aby przeanalizować, jak działa natywne leniwe ładowanie w narzędziach programistycznych, możesz rozpocząć zabawę od poniższej wersji demonstracyjnej. W tym przypadku nie jest używany ani jeden wiersz JavaScript . Tak, to po prostu pełne natywne leniwe ładowanie.

  • Przetestuj natywne demo z leniwym ładowaniem

Czego możesz się spodziewać : wszystkie obrazy są pobierane jednocześnie, ale z różnymi odpowiedziami HTTP. Te z kodem odpowiedzi 200 są obrazami ładowanymi z zapałem, podczas gdy te z kodem odpowiedzi 206 są tylko częściowo pobierane w celu uzyskania wstępnych informacji o obrazach. Te obrazy zostaną następnie całkowicie pobrane z kodem odpowiedzi 200 po przewinięciu w dół.

Demonstracja hybrydowego leniwego ładowania

Aby przeanalizować, jak działa hybrydowe leniwe ładowanie, możesz zacząć grać z następnym demo. Tutaj używany jest [email protected] , a opcja use_native jest ustawiona na true :

  • Przetestuj demonstrację hybrydowego lazy loading

Czego się spodziewać : wypróbuj wersję demonstracyjną w różnych przeglądarkach, aby zobaczyć, jak działa. W przeglądarkach obsługujących natywne ładowanie z opóźnieniem zachowanie będzie takie samo, jak w wersji demonstracyjnej natywnego ładowania z opóźnieniem. W przeglądarkach, które nie obsługują natywnego lazy loading, obrazy będą pobierane podczas przewijania w dół.

Zwróć uwagę, że vanilla-lazyload używa interfejsu API IntersectionObserver pod maską, więc musisz go wypełnić w Internet Explorerze i nowszych wersjach Safari. Nie jest to jednak wielka sprawa, jeśli nie podano wypełnienia, ponieważ w takim przypadku vanilla-lazyload po prostu pobrałby wszystkie obrazy naraz.

Uwaga : Przeczytaj więcej w rozdziale „Do wypełniania lub nie do wypełniania” w pliku readme vanilla-lazyload .

Wypróbuj hybrydowe leniwe ładowanie na swojej stronie internetowej

Ponieważ natywne leniwe ładowanie pojawi się wkrótce w niektórych przeglądarkach, dlaczego nie dać mu szansy dzisiaj, używając hybrydowego leniwego ładowania? Oto, co musisz zrobić:

Znacznik HTML

Najprostszym znacznikiem obrazu są dwa atrybuty: src i alt .

W przypadku obrazów powyżej części strony należy pozostawić atrybut src i dodać atrybut loading="eager" .

 <img src="important.jpg" loading="eager" alt="Important image">

W przypadku obrazów w części strony widocznej na ekranie należy zastąpić atrybut src atrybutem danych data-src i dodać atrybut loading="lazy" .

 <img data-src="lazy.jpg" loading="lazy" alt="A lazy image">

Jeśli chcesz używać elastycznych obrazów, zrób to samo z srcset i sizes .

 <img alt="A lazy image" loading="lazy" data-src="lazy.jpg">

Jeśli wolisz używać znacznika picture , zmień srcset , sizes i src również w znacznikach source .

 <picture> <source media="(min-width: 1200px)"> <source media="(min-width: 800px)"> <img alt="A lazy image" loading="lazy" data-src="lazy.jpg"> </picture>

Znacznik picture może być również używany do selektywnego ładowania formatu WebP dla twoich obrazów.

Uwaga : Jeśli chcesz dowiedzieć się więcej o zastosowaniach vanilla-lazyload , przeczytaj sekcję HTML „Wprowadzenie” w pliku readme.

Kod JavaScript

Przede wszystkim musisz zawrzeć vanilla-lazyload na swojej stronie.

Możesz go załadować z CDN, takiego jak jsDelivr:

 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Lub możesz zainstalować go za pomocą npm:

 npm install vanilla-lazyload@12

Możliwe jest również użycie skryptu async z automatyczną inicjalizacją; załaduj go jako moduł ES, używając type="module" lub załaduj jako AMD, używając RequireJS. Znajdź więcej sposobów dołączania i używania vanilla-lazyload w sekcji skryptu „Pierwsze kroki” w pliku readme.

Następnie w kodzie JavaScript swojej witryny/aplikacji internetowej umieść następujące informacje:

 var pageLazyLoad = new LazyLoad({ elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading });

Uwaga : Skrypt ma wiele innych ustawień, których możesz użyć, aby dostosować zachowanie vanilla-lazyload , np. aby zwiększyć odległość obszaru przewijania, od którego zaczyna się ładowanie elementów lub ładować elementy tylko wtedy, gdy pozostają w widoku przez jakiś czas. dany czas. Znajdź więcej ustawień w sekcji API pliku readme.

Wszystko razem, używając skryptu async

Aby zebrać to wszystko razem i użyć skryptu async w celu zmaksymalizowania wydajności, zapoznaj się z następującym kodem HTML i JavaScript:

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <!-- Set the options for the global instance of vanilla-lazyload --> <script> window.lazyLoadOptions = { elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading }; </script> <!-- Include vanilla lazyload 12 through an async script --> <script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Otóż ​​to! Dzięki tym bardzo prostym i łatwym krokom włączysz hybrydowe leniwe ładowanie na swojej stronie internetowej!

Ważne najlepsze praktyki

  • Zastosuj leniwe ładowanie tylko do obrazów, o których wiesz, że prawdopodobnie będą wyświetlane w części strony widocznej na ekranie. Chętnie ładuj te znajdujące się nad zakładką, aby zmaksymalizować wydajność. Jeśli po prostu zastosujesz leniwe ładowanie do wszystkich obrazów na stronie, zmniejszysz wydajność renderowania.
  • Użyj CSS, aby zarezerwować trochę miejsca na obrazy przed ich załadowaniem. W ten sposób wypchną resztę treści poniżej. Jeśli tego nie zrobisz, większa liczba obrazów zostanie umieszczona w części widocznej na ekranie, zanim powinny, powodując ich natychmiastowe pobieranie. Jeśli potrzebujesz do tego sztuczki CSS, możesz ją znaleźć w sekcji porad i wskazówek w pliku readme vanilla-lazyload .

Plusy i minusy

Native LAZY LOADING
ZALETY
  • Nie wymaga JavaScript;
  • Bez kłopotów z konfiguracją, po prostu działa;
  • Nie ma potrzeby rezerwowania miejsca na obrazy za pomocą sztuczek CSS;
CONS
  • Nie działa dzisiaj we wszystkich przeglądarkach;
  • Początkowy ładunek jest wyższy z powodu wstępnego pobierania początkowych 2 kb dla każdego obrazu.
LAZY LOADING OPARTY NA JAVASCRIPT
ZALETY
  • Działa konsekwentnie we wszystkich przeglądarkach, teraz;
  • Możesz wykonywać bardzo spersonalizowane sztuczki interfejsu użytkownika, takie jak efekt rozmycia lub opóźnione ładowanie.
CONS
  • Opiera się na JavaScript, aby załadować zawartość.
LAZY HYBRYDOWE ŁADOWANIE
ZALETY
  • Daje możliwość włączenia i przetestowania natywnego leniwego ładowania, jeśli jest obsługiwane;
  • Umożliwia leniwe ładowanie we wszystkich przeglądarkach;
  • Możesz w przejrzysty sposób usunąć zależność od skryptu, gdy tylko natywna obsługa opóźnionego ładowania będzie rozpowszechniona.
CONS
  • Nadal korzysta z JavaScript, aby załadować zawartość.

Zawijanie

Jestem bardzo podekscytowany, że natywne leniwe ładowanie pojawi się w przeglądarkach i nie mogę się doczekać, aż wszyscy dostawcy przeglądarek to zaimplementują!

W międzyczasie możesz albo wzbogacić znaczniki HTML w celu progresywnego ulepszania i uzyskać natywne leniwe ładowanie tylko tam, gdzie jest to obsługiwane, albo wybrać hybrydowe ładowanie z opóźnieniem i uzyskać zarówno natywne, jak i oparte na JavaScript ładowanie leniwe do dnia, w którym leniwe ładowanie natywne będzie być obsługiwane przez zdecydowaną większość przeglądarek.

Spróbuj! Nie zapomnij o gwiazdkach/oglądaj vanilla-lazyload na GitHubie i daj mi znać swoje przemyślenia w sekcji komentarzy.

Dalsze czytanie na SmashingMag:

  • Teraz mnie widzisz: jak odroczyć, leniwie ładować i działać za pomocą IntersectionObserver
  • Leniwe ładowanie modułów JavaScript za pomocą ConditionerJS
  • Lista kontrolna wydajności front-endu 2019 (PDF, Apple Pages, MS Word)
  • Jak poprawa wydajności strony internetowej może pomóc ocalić planetę?