Obrazy i elementy <iframe>
często zużywają więcej przepustowości niż inne typy zasobów. W przypadku elementów <iframe>
wczytywanie i renderowanie zawartych w nich stron może wymagać dodatkowego czasu przetwarzania.
W przypadku leniwego wczytywania obrazów opóźnianie wczytywania obrazów znajdujących się poza początkowym widokiem może pomóc w zmniejszeniu konkurencji o pasmo w przypadku bardziej krytycznych zasobów w początkowym widoku. W niektórych przypadkach, gdy połączenia z siecią są słabe, może to poprawić największe wyrenderowanie treści (LCP) strony, a przekierowanie przepustowości może przyspieszyć wczytywanie i wyświetlanie elementów kandydujących na LCP.
W przypadku elementów <iframe>
można poprawić czas interakcji do kolejnego wyrenderowania (INP) strony, stosując opóźnione wczytywanie. Dzieje się tak, ponieważ <iframe>
to zupełnie osobny dokument HTML ze swoimi własnymi zasobami podrzędnymi.
Chociaż elementy <iframe>
mogą być uruchamiane w oddzielnym procesie, często współdzielą one proces z innymi wątkami, co może powodować, że strony stają się mniej responsywne na działania użytkownika.
Dlatego warto odłożyć wczytywanie obrazów i elementów <iframe>
, które nie są widoczne na ekranie. Wymaga to niewielkiego wysiłku, a przynosi całkiem dobre rezultaty. Z tego modułu dowiesz się, jak stosować opóźnione wczytywanie tych dwóch typów elementów, aby zapewnić szybsze i wygodniejsze działanie strony w krytycznym okresie uruchamiania.
Leniwe ładowanie obrazów za pomocą atrybutu loading
Do elementów <img>
można dodać atrybut loading
, aby informować przeglądarki, jak mają być one wczytywane:
"eager"
informuje przeglądarkę, że obraz powinien zostać załadowany natychmiast, nawet jeśli znajduje się poza początkowym obszarem widoku. Jest to też domyślna wartość atrybutuloading
."lazy"
opóźnia wczytywanie obrazu, dopóki nie znajdzie się w określonym zakresie widocznego obszaru. Ta odległość różni się w zależności od przeglądarki, ale często jest ustawiona na tyle dużą, że obraz wczytuje się, gdy użytkownik przewinie do niego kursorem.
Warto też pamiętać, że jeśli używasz elementu <picture>
, atrybut loading
powinien być nadal stosowany do elementu podrzędnego <img>
, a nie elementu <picture>
. Dzieje się tak, ponieważ element <picture>
to kontener zawierający dodatkowe elementy <source>
wskazujące różne obrazy docelowe, a wybrany przez przeglądarkę obraz docelowy jest stosowany bezpośrednio do elementu podrzędnego <img>
.
Nie ładuj leniwie obrazów, które znajdują się w początkowo widocznym obszarze
Atrybut loading="lazy"
należy dodawać tylko do elementów <img>
, które znajdują się poza początkowym widocznym obszarem. Jednak ustalenie dokładnej pozycji elementu w widocznym obszarze przed wyrenderowaniem strony może być trudne. Trzeba wziąć pod uwagę różne rozmiary widocznego obszaru, formaty obrazu i urządzenia.
Na przykład widok na komputerze może się znacznie różnić od widoku na telefonie, ponieważ wyświetla więcej miejsca w pionie, co pozwala zmieścić w początkowym widoku obrazy, które nie mieszczą się w początkowym widoku na fizycznie mniejszym urządzeniu. Na tabletach używanych w orientacji pionowej również wyświetlana jest znaczna ilość miejsca w pionie, być może nawet więcej niż na niektórych komputerach.
Są jednak przypadki, w których należy unikać stosowania loading="lazy"
. Na przykład w przypadku obrazów tytułowych lub innych obrazów, które prawdopodobnie będą wyświetlane powyżej obszaru składania lub u góry układu na dowolnym urządzeniu, należy pominąć atrybut loading="lazy"
w elementach <img>
.<img>
Jest to szczególnie ważne w przypadku obrazów, które prawdopodobnie będą kandydatami do LCP.
Obrazy wczytywane z opóźnieniem muszą poczekać, aż przeglądarka zakończy układanie, aby wiedzieć, czy ich ostateczna pozycja znajduje się w obszarze widoku. Oznacza to, że jeśli element <img>
w widocznym widoku ma atrybut loading="lazy"
, jest on wczytywany dopiero po pobraniu, przeanalizowaniu i zastosowaniu wszystkich zasobów CSS do strony, a nie od razu, gdy zostanie wykryty przez skaner wstępnego wczytania w surowym znaczniku.
Atrybut loading
elementu <img>
jest obsługiwany we wszystkich głównych przeglądarkach, więc nie trzeba używać JavaScriptu do opóźnionego wczytywania obrazów. Dodanie dodatkowego kodu JavaScriptu do strony w celu udostępnienia funkcji, które są już dostępne w przeglądarce, wpływa na inne aspekty wydajności strony, takie jak INP.
Demonstracja leniwego ładowania obrazów
Leniwe ładowanie elementów <iframe>
Łagodne wczytywanie elementów <iframe>
do momentu, aż będą one widoczne w widoku, może pozwolić zaoszczędzić znaczną ilość danych i przyspieszyć wczytywanie kluczowych zasobów, które są niezbędne do wczytania strony najwyższego poziomu. Dodatkowo elementy <iframe>
to w podstawie całe dokumenty HTML wczytane w dokumencie najwyższego poziomu, więc mogą one zawierać znaczną liczbę zasobów podrzędnych, zwłaszcza JavaScriptu, co może znacznie wpłynąć na INP strony, jeśli zadania w tych ramach wymagają znacznej ilości czasu przetwarzania.
Wstawianie elementów innych firm jest typowym przypadkiem użycia elementów <iframe>
. Na przykład osadzone odtwarzacze wideo lub posty w mediach społecznościowych często używają elementów <iframe>
, które wymagają znacznej liczby zasobów podrzędnych, co może też powodować ograniczenie przepustowości zasobów strony najwyższego poziomu. Na przykład zwinne wczytywanie kodu embedowanego filmu z YouTube pozwala zaoszczędzić ponad 500 KiB podczas początkowego wczytywania strony, a zwinne wczytywanie wtyczki przycisku polubienia Facebooka pozwala zaoszczędzić ponad 200 KiB, z czego większość to kod JavaScript.
W każdym razie, jeśli masz element <iframe>
w części strony widocznej po przewinięciu, rozważ jego ładowanie leniwe, jeśli nie jest to konieczne. Może to znacznie poprawić wrażenia użytkowników.
Atrybut loading
w elementach <iframe>
Atrybut loading
w elementach <iframe>
jest też obsługiwany we wszystkich głównych przeglądarkach. Wartości atrybutu loading
i ich zachowanie są takie same jak w przypadku elementów <img>
, które używają atrybutu loading
:
- Wartością domyślną jest
"eager"
. Informuje przeglądarkę, aby natychmiast wczytała kod HTML elementu<iframe>
i jego zasoby podrzędne. "lazy"
opóźnia wczytywanie kodu HTML elementu<iframe>
i jego zasobów podrzędnych do momentu, gdy znajdzie się w wyznaczonym z góry obszarze widocznym.
Demonstracja leniwego ładowania elementów iframe
Fasady
Zamiast wczytywać element osadzony od razu podczas wczytywania strony, możesz go wczytać na żądanie w odpowiedzi na działanie użytkownika. Możesz to zrobić, wyświetlając obraz lub inny odpowiedni element HTML, dopóki użytkownik z nim nie wejdzie w interakcję. Gdy użytkownik wejdzie w interakcję z elementem, możesz go zastąpić elementem zewnętrznym. Ta technika nosi nazwę fasadowej.
Często stosowane zastosowanie fasad to umieszczanie filmów z usług zewnętrznych, które może wiązać się z wczytywaniem wielu dodatkowych i potencjalnie drogich zasobów podrzędnych (np. JavaScript) oprócz samego filmu. W takim przypadku – chyba że istnieje uzasadniona potrzeba automatycznego odtwarzania filmu – filmy osadzone wymagają interakcji użytkownika przed odtworzeniem, czyli kliknięcia przycisku odtwarzania.
To świetna okazja, aby wyświetlić obraz statyczny, który wizualnie przypomina wbudowany film, i tym samym zaoszczędzić znaczną ilość przepustowości. Gdy użytkownik kliknie obraz, zostanie on zastąpiony przez właściwy element <iframe>
, co spowoduje rozpoczęcie pobierania kodu HTML elementu <iframe>
i jego zasobów podrzędnych.
Oprócz poprawy początkowego wczytywania strony kolejną ważną zaletą jest to, że jeśli użytkownik nigdy nie odtworzy filmu, zasoby potrzebne do jego wyświetlenia nigdy nie zostaną pobrane. Jest to dobry wzór, ponieważ zapewnia, że użytkownik pobiera tylko to, czego rzeczywiście chce, bez tworzenia błędnych założeń dotyczących jego potrzeb.
Widżety czatu to kolejny świetny przykład zastosowania techniki fasady. Większość widżetów czatu pobiera znaczne ilości kodu JavaScript, który może negatywnie wpływać na wczytywanie strony i jej responsywność na dane wprowadzane przez użytkownika. Podobnie jak w przypadku wczytywania innych elementów, koszt jest naliczany w momencie wczytania, ale w przypadku widżetu czatu nie każdy użytkownik będzie z niego korzystać.
Z użyciem komponentu fasadowego można zastąpić zewnętrzny przycisk „Rozpocznij czat” fałszywym przyciskiem. Gdy użytkownik wejdzie w interaktywny kontakt z widżetem (np. przez przytrzymanie wskaźnika przez odpowiedni czas lub kliknięcie), gdy będzie tego potrzebować, pojawi się właściwy, funkcjonalny widżet czatu.
Możesz oczywiście tworzyć własne fasady, ale dostępne są też opcje open source dla popularnych usług zewnętrznych, np. lite-youtube-embed
do filmów w YouTube, lite-vimeo-embed
do filmów w Vimeo i React Live Chat Loader do widżetów czatu.
Biblioteki JavaScript do ładowania opóźnionego
Jeśli chcesz wczytywać elementy <video>
, obrazy <video>
elementu poster
, obrazy wczytywane przez właściwość CSS background-image
lub inne nieobsługiwane elementy z opóźnieniem, możesz to zrobić za pomocą rozwiązania opartego na JavaScript, takiego jak lazysizes lub yall.js, ponieważ opóźnione wczytywanie tego typu zasobów nie jest funkcją na poziomie przeglądarki.
W szczególności elementy <video>
odtwarzane automatycznie i zapętlane bez ścieżki dźwiękowej są znacznie skuteczniejszą alternatywą niż animowane GIF-y, które często mogą być kilkakrotnie większe niż zasoby wideo o porównywalnej jakości wizualnej. Mimo to te filmy mogą nadal zajmować znaczną część przepustowości, dlatego ich ładowanie opóźnione jest dodatkową optymalizacją, która może znacznie ograniczyć marnowanie przepustowości.
Większość tych bibliotek działa za pomocą interfejsu IntersectionObserver API, a dodatkowo interfejsu MutationObserver API, jeśli kod HTML strony zmienia się po początkowym wczytaniu, aby wykrywać moment, w którym element pojawia się w widoku użytkownika. Jeśli obraz jest widoczny lub zbliża się do widocznego obszaru, biblioteka JavaScript zastąpi niestandardowy atrybut (często data-src
lub podobny) poprawnym atrybutem, np. src
.
Załóżmy, że masz film, który zastępuje animowany GIF, ale chcesz go wczytywać z opóźnieniem za pomocą rozwiązania JavaScript. Możliwe jest to za pomocą yall.js z tym wzorcem znaczników:
<!-- The autoplay, loop, muted, and playsinline attributes are to
ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
<source data-src="video.webm" type="video/webm">
<source data-src="video.mp4" type="video/mp4">
</video>
Domyślnie yall.js obserwuje wszystkie odpowiednie elementy HTML z klasą "lazy"
. Gdy yall.js zostanie wczytany i wykonany na stronie, film nie wczytuje się, dopóki użytkownik nie przewinie go do widocznego obszaru. W tym momencie atrybuty data-src
elementów podrzędnych <source>
elementu <video>
są zastępowane atrybutami src
, co powoduje wysłanie żądania pobrania filmu i automatyczne jego odtworzenie.
Sprawdź swoją wiedzę
Jaka jest domyślna wartość atrybutu loading
w przypadku elementów <img>
i <iframe>
?
"eager"
"lazy"
Kiedy warto stosować rozwiązania oparte na opóźnionym wczytywaniu kodu JavaScript?
loading
nie jest obsługiwany, np. w przypadku filmów odtwarzanych automatycznie, które mają zastąpić animowane obrazy lub wczytać z opóźnieniem obraz plakatu elementu <video>
.
Kiedy fasada jest przydatną techniką?
Następny temat: pobieranie z wyprzedzeniem i wstępne renderowanie
Teraz, gdy już wiesz, jak działa wczytywanie opóźnione obrazów i elementów <iframe>
, możesz sprawić, aby strony wczytywały się szybciej, a jednocześnie spełniały potrzeby użytkowników. Są jednak przypadki, w których spekulacyjne wczytywanie zasobów może być pożądane. W następnym module dowiesz się więcej o wstępnym pobieraniu i renderowaniu oraz o tym, jak te techniki, jeśli są używane ostrożnie, mogą znacznie przyspieszyć przechodzenie do kolejnych stron przez ich wcześniejsze wczytywanie.