Podobnie jak w przypadku elementów graficznych, film możesz też leniwie ładować. Filmy są zwykle ładowane za pomocą elementu <video>
(chociaż inna metoda wykorzystująca metodę <img>
jest dostępna w ograniczonym zakresie). Sposób leniwego ładowania <video>
zależy jednak od konkretnego przypadku użycia. Omówmy kilka scenariuszy,
które wymagają innego rozwiązania.
Filmy, które nie odtwarzają się automatycznie
W przypadku filmów, w których odtwarzanie jest inicjowane przez użytkownika (czyli takich, które nie są odtwarzane automatycznie), wskazane może być określenie atrybutu preload
w elemencie <video>
:
<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
W powyższym przykładzie atrybut preload
o wartości none
uniemożliwia przeglądarkom wstępne wczytywanie jakich danych wideo. Atrybut poster
udostępnia elementowi <video>
obiekt zastępczy, który zajmie całą przestrzeń podczas wczytywania filmu. Dzieje się tak, ponieważ domyślne zachowanie wczytywania filmu może się różnić w zależności od przeglądarki:
- W Chrome domyślną wartością parametru
preload
byłoauto
, a od Chrome 64 wartość domyślna tometadata
. Jednak w komputerowej wersji Chrome część filmu może być wstępnie wczytywana za pomocą nagłówkaContent-Range
. Inne przeglądarki oparte na Chromium i Firefox działają podobnie. - Podobnie jak w Chrome na komputerze, przeglądarka Safari w wersji 11.0 na komputery wstępnie wczytuje zakres filmów. Od wersji 11.2 wstępnie wczytywane są tylko metadane filmu. W Safari w systemie iOS filmy nigdy nie są wstępnie wczytywane.
- Gdy włączony jest tryb oszczędzania danych,
preload
domyślnie przyjmuje wartośćnone
.
Domyślne zachowania przeglądarki w odniesieniu do strony preload
nie są ustalone bezwzględnie, dlatego najprawdopodobniej najlepiej będzie wyrażać zgodę na wulgaryzmy. W takich przypadkach, gdy użytkownik inicjuje odtwarzanie, najprostszym sposobem na odroczenie wczytywania filmu na wszystkich platformach jest użycie właściwości preload="none"
. Atrybut preload
nie jest jedynym sposobem na opóźnienie wczytywania treści wideo. Szybkie odtwarzanie ze wstępnym wczytywaniem filmów może podsunąć Ci pomysły i wgląd na temat pracy z odtwarzaniem filmów w języku JavaScript.
Niestety ta funkcja nie jest przydatna, gdy chcesz użyć filmu zamiast animowanych GIF-ów. Opisaliśmy je w następnej kolejności.
Film pełniący funkcję animowanego zamiennika GIF-a
Animowane GIF-y mają szerokie zastosowanie, ale pod wieloma względami nie są od nich odpowiedniki, zwłaszcza pod względem rozmiaru plików. Animowane pliki GIF mogą trwać do kilku megabajtów danych. Filmy o podobnej jakości wizualnej są zwykle znacznie mniejsze.
Użycie elementu <video>
jako zamiennika animowanego GIF-a nie jest tak proste jak element <img>
. Animowane pliki GIF mają trzy cechy:
- Po wczytaniu są odtwarzane automatycznie.
- Są one odtwarzane w pętli (chociaż nie zawsze tak jest).
- Nie mają ścieżki audio.
Jeśli chcesz to osiągnąć za pomocą elementu <video>
, wygląda to mniej więcej tak:
<video autoplay muted loop playsinline>
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Atrybuty autoplay
, muted
i loop
nie są jasne.
Parametr playsinline
jest niezbędny do autoodtwarzania na iOS. Teraz możesz skorzystać z dostępnego
zamiennika filmu jako GIF-a, który działa na różnych platformach. Ale jak go leniwie wczytywać? Aby rozpocząć, odpowiednio zmodyfikuj znaczniki <video>
:
<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
<source data-src="one-does-not-simply.webm" type="video/webm">
<source data-src="one-does-not-simply.mp4" type="video/mp4">
</video>
Dodaliśmy też atrybut poster
, który umożliwia wstawianie zmiennej zajmującej miejsce w elemencie <video>
do czasu leniwego ładowania filmu. Tak jak w przypadku przykładów leniwego ładowania <img>
, umieść adres URL filmu w atrybucie data-src
w każdym elemencie <source>
. Następnie użyj kodu JavaScript podobnego do przykładów leniwego ładowania obrazów opartych na obserwacji Intersection:
document.addEventListener("DOMContentLoaded", function() {
var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));
if ("IntersectionObserver" in window) {
var lazyVideoObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(video) {
if (video.isIntersecting) {
for (var source in video.target.children) {
var videoSource = video.target.children[source];
if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
videoSource.src = videoSource.dataset.src;
}
}
video.target.load();
video.target.classList.remove("lazy");
lazyVideoObserver.unobserve(video.target);
}
});
});
lazyVideos.forEach(function(lazyVideo) {
lazyVideoObserver.observe(lazyVideo);
});
}
});
Gdy używasz leniwego ładowania elementu <video>
, musisz powtórzyć wszystkie elementy podrzędne <source>
i zmienić ich atrybuty data-src
na atrybuty src
. Gdy to zrobisz, musisz wywołać ładowanie filmu, wywołując metodę load
elementu, co spowoduje automatyczne rozpoczęcie odtwarzania multimediów zgodnie z atrybutem autoplay
.
Korzystając z tej metody, otrzymujesz rozwiązanie wideo, które emuluje animowane zachowania GIF-ów, ale nie wymaga angażowania danych w taki sam sposób jak animowane GIF-y. Treści można też ładować leniwie.
Leniwe ładowanie bibliotek
W przypadku leniwego ładowania filmów mogą Ci pomóc te biblioteki:
- vanilla-lazyload i lozad.js to bardzo lekkie opcje, które korzystają tylko z intersection Observer. Z tego względu są one bardzo wydajne, ale przed użyciem w starszych przeglądarkach trzeba je wypełnić.
- yall.js to biblioteka, która korzysta z obserwacji intersekcji i korzysta z modułów obsługi zdarzeń. Może też leniwie wczytywać obrazy filmu
poster
za pomocą atrybutudata-poster
. - Jeśli potrzebujesz biblioteki leniwego ładowania specyficznej dla React, możesz użyć funkcji react-lazyload. Nie korzysta on z intersection Observer, ale zapewnia znaną metodę leniwego wczytywania obrazów dla osób przyzwyczajonych do tworzenia aplikacji w React.
Każda z tych bibliotek leniwego ładowania jest dobrze udokumentowana i zawiera wiele wzorców znaczników przydatnych w różnych zadaniach związanych z leniwym ładowaniem.