Hybrydowe leniwe ładowanie: progresywna migracja do natywnego leniwego ładowania
Opublikowany: 2022-03-10W 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">
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 atrybutusrc
; - 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 |
|
CONS |
|
LAZY LOADING OPARTY NA JAVASCRIPT | |
---|---|
ZALETY |
|
CONS |
|
LAZY HYBRYDOWE ŁADOWANIE | |
---|---|
ZALETY |
|
CONS |
|
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ę?