Pubblicato il 16 agosto 2019, ultimo aggiornamento il 2 luglio 2026
Come per gli elementi immagine, potresti anche voler caricare lentamente i video. I video vengono in genere caricati con l'elemento <video>, anche se per i video ospitati su altri servizi come YouTube possono utilizzare <iframe> (in questo caso, consulta l'articolo sul caricamento lento degli iframe).
La modalità di caricamento lento di <video> dipende dal caso d'uso, poiché esistono diverse soluzioni.
Utilizzare l'attributo loading
I browser hanno iniziato a supportare l'loading attributo sugli elementi multimediali (<video> e <audio>). Se supportato, ciò significa che sia i contenuti multimediali sia qualsiasi immagine di anteprima vengono caricati lentamente automaticamente semplicemente aggiungendo l'loading="lazy" attributo:
<video controls loading="lazy" 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>
L'utilizzo di loading="lazy" impedisce il caricamento dell'immagine poster fino a quando non si trova nel riquadro visibile o nelle sue vicinanze, quindi utilizza l'attributo preload per decidere la quantità di video da caricare. Ciò significa anche che i video autoplay non verranno riprodotti automaticamente fino a quando non si trovano nel riquadro visibile o nelle sue vicinanze. L'attributo loading="lazy" funziona con gli attributi poster, preload e autoplay e non li sostituisce.
I browser che non supportano l'attributo loading sugli elementi multimediali lo ignoreranno, il che comporterà il caricamento immediato dell'immagine poster e il caricamento del video in base all'attributo preload, che tratteremo di seguito.
Utilizzare l'attributo preload per caricare lentamente i video che non vengono riprodotti automaticamente
In genere, è consigliabile evitare i video con riproduzione automatica, in quanto lasciano il controllo all'utente. In questi casi, specificare l'attributo preload sull'elemento <video> è il modo migliore per evitare di caricare l'intero video fino a quando non è necessario:
<video controls loading="lazy" 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>
L'esempio precedente utilizza un attributo preload con un valore di none per impedire ai browser di precaricare qualsiasi dato video, anche quando si trova nel riquadro visibile. L'attributo poster assegna all'elemento <video> un segnaposto che occuperà lo spazio durante il caricamento del video.
Nella maggior parte dei browser, preload è impostato per impostazione predefinita su metadata e una parte del video viene precaricata utilizzando l'intestazione Content-Range. Ciò può comportare il download di più dati del previsto: i browser non possono sapere in quali byte sono memorizzati i metadati e potrebbero non essere memorizzati all'inizio del file. Pertanto, la probabilità di evitare il caricamento del video è maggiore se si utilizza preload="none".
Questo può essere ulteriormente migliorato per precaricare i metadati quando l'utente passa il mouse sopra il video con un attributo onmouseenter (o con il gestore di eventi mouseenter equivalente):
<video controls
loading="lazy"
preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
In questo modo non solo si riduce il ritardo quando l'utente riproduce il video, ma viene anche mostrata la durata del video non appena lo fa.
I video possono essere candidati LCP. Un'immagine poster verrà caricata più rapidamente del video, quindi, se si tratta di un candidato LCP, devi utilizzare un'immagine di anteprima, ma anche precaricarla con un valore dell'attributo fetchpriority di "high", poiché al momento della stesura non puoi specificare il fetchpriority per gli attributi poster:
<link rel="preload" href="one-does-not-simply-placeholder.jpg" as="image" fetchpriority="high">
<video controls preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
I video che sono elementi LCP non devono utilizzare loading="lazy"—allo stesso modo, non devi caricare lentamente le immagini LCP video.
Per i video che fungono da sostituzione delle GIF animate
I video con riproduzione automatica vengono comunemente utilizzati per le animazioni rapide in stile GIF. Sebbene le GIF animate siano ampiamente utilizzate, sono inferiori agli equivalenti video in diversi modi, in particolare per le dimensioni dei file. Le GIF animate possono raggiungere diversi megabyte di dati. I video di qualità visiva simile tendono a essere molto più piccoli.
L'utilizzo dell'elemento <video> come sostituzione delle GIF animate non è semplice come l'elemento <img>. Le GIF animate hanno tre caratteristiche:
- Vengono riprodotte automaticamente al caricamento.
- Vengono riprodotte in loop continuo (anche se non è sempre così).
- Non hanno una traccia audio.
Per ottenere questo risultato con l'elemento <video>:
<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>
L'attributo loading="lazy" evita di caricare il video fino a quando non si trova vicino al riquadro visibile. Gli attributi autoplay, muted e loop sono autoesplicativi. playsinline è necessario per la riproduzione automatica in iOS.
Ora hai una sostituzione video-GIF utilizzabile che funziona su tutte le piattaforme. Ma come si fa a caricarlo lentamente?
Per i browser che supportano questa opzione, loading="lazy" è la più semplice:
<video loading="lazy" 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>
Per supportare il caricamento lento dei video in altri browser, devi utilizzare JavaScript e modificare di conseguenza il markup <video>:
<video class="lazy" preload="none" controls muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
Noterai la rimozione di autoplay e l'aggiunta degli attributi class="lazy", preload="none" e poster, che ti consentono di specificare un segnaposto per occupare lo spazio dell'elemento <video> fino a quando il video non viene caricato lentamente. Poi, utilizziamo un Intersection Observer JavaScript per riattivare la riproduzione automatica:
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) {
video.target.removeAttribute('preload');
video.target.removeAttribute('controls');
video.target.autoplay = true;
video.target.classList.remove("lazy");
lazyVideoObserver.unobserve(video.target);
}
});
});
lazyVideos.forEach(function(lazyVideo) {
lazyVideoObserver.observe(lazyVideo);
});
}
});
Con questo metodo, il video non viene riprodotto automaticamente per impostazione predefinita e solo quando l'Intersection Observer rileva che il video entra nel riquadro visibile. Inoltre, l'attributo controls gestisce i casi in cui JavaScript non funziona. Insieme, ciò significa che hai una soluzione video che emula il comportamento delle GIF animate, ma non comporta lo stesso utilizzo intensivo dei dati delle GIF animate e puoi caricare lentamente questi contenuti.
Librerie di caricamento lento
Le seguenti librerie possono aiutarti a caricare lentamente i video:
- vanilla-lazyload e lozad.js sono opzioni molto leggere che utilizzano solo Intersection Observer. Pertanto, sono altamente performanti, ma devono essere polyfill prima di poter essere utilizzate sui browser meno recenti.
- Se hai bisogno di una libreria di caricamento lento specifica per React, potresti prendere in considerazione react-lazyload. Sebbene non utilizzi Intersection Observer, fornisce un metodo familiare di caricamento lento delle immagini per chi è abituato a sviluppare applicazioni con React.
Ognuna di queste librerie di caricamento lento è ben documentata e include molti pattern di markup per i vari tentativi di caricamento lento.
Man mano che l'attributo loading per <video> diventa disponibile in un numero maggiore di browser, prevediamo che le soluzioni JavaScript (incluse le librerie) vengano utilizzate meno a favore delle soluzioni integrate, ad eccezione di quelle che richiedono un controllo maggiore di quello consentito.