Publicado em 16 de agosto de 2019
Assim como nos elementos de imagem, você também pode carregar vídeos de forma lenta. Os vídeos geralmente são carregados com o elemento <video>
, mas para vídeos hospedados em outros serviços, como o YouTube, eles podem usar <iframe>
s. Nesse caso, confira o artigo sobre iframes de carregamento lento.
A forma de carregar <video>
de forma lenta depende do caso de uso, já que há algumas soluções diferentes.
Para vídeos que não têm reprodução automática
A prática recomendada é evitar a reprodução automática de vídeos, porque isso deixa o controle com o usuário. Nesses casos, especificar o atributo preload
no elemento <video>
é a melhor maneira de evitar o carregamento de todo o vídeo:
<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>
O exemplo anterior usa um atributo preload
com um valor de none
para impedir que os navegadores carreguem qualquer dado de vídeo. O atributo poster
dá ao elemento <video>
um marcador de posição que ocupa o espaço enquanto o vídeo é carregado.
Na maioria dos navegadores, o padrão de preload
é metadata
, e uma parte do vídeo é pré-carregada usando o cabeçalho Content-Range
. Isso pode resultar no download de mais dados do que o desejado, principalmente se o cabeçalho Content-Range
não tiver suporte do navegador. Mesmo com suporte, os navegadores não podem saber em quais bytes os metadados estão armazenados, e eles podem não estar no início do arquivo. Portanto, a melhor chance de evitar o carregamento do vídeo é especificar none
e usar preload="none"
.
Isso pode ser aprimorado para pré-carregar os metadados quando o usuário passa o cursor sobre o vídeo com um atributo onmouseenter
(ou com o manipulador de eventos mouseenter
equivalente):
<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>
Isso não apenas reduz o atraso quando o usuário começa a reproduzir o vídeo, mas também mostra a duração do vídeo assim que ele.
Os vídeos podem se qualificar como candidatos para a LCP. Uma imagem poster
será carregada mais rápido do que o vídeo. Portanto, se esse for um candidato a LCP, use uma imagem de capa, mas também pré-carregue com um valor de atributo fetchpriority
de "high"
:
<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>
Para vídeos que substituem GIFs animados
Os vídeos com reprodução automática são mais usados para animações rápidas no estilo GIF. Embora os GIFs animados sejam muito usados, eles são inferiores aos equivalentes em vídeo de várias maneiras, principalmente no tamanho do arquivo. Os GIFs animados podem ter vários megabytes de dados. Vídeos de qualidade visual semelhante tendem a ser muito menores.
O uso do elemento <video>
como substituto de GIFs animados não é tão simples quanto o elemento <img>
. Os GIFs animados têm três características:
- Eles são reproduzidos automaticamente quando carregados.
- Elas são executadas continuamente (mas nem sempre é assim).
- Não tem uma faixa de áudio.
Para fazer isso com o elemento <video>
, faça o seguinte:
<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>
Os atributos autoplay
, muted
e loop
são autoexplicativos. playsinline
é necessário para que a reprodução automática ocorra no iOS. Agora você tem uma substituição de vídeo como GIF que funciona em várias plataformas. Mas como fazer o carregamento lento? Para começar, modifique a marcação <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>
Você vai notar a adição do atributo poster
, que permite especificar um marcador de posição para ocupar o espaço do elemento <video>
até que o vídeo seja carregado de forma lazy. Assim como nos exemplos de carregamento lento de <img>
, armazene o URL do vídeo no atributo data-src
em cada elemento <source>
. Em seguida, use um código JavaScript semelhante aos exemplos de carregamento lento de imagem baseado no Intersection Observer:
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);
});
}
});
Quando você carrega um elemento <video>
de forma lenta, é necessário iterar por todos os elementos <source>
filhos e inverter os atributos data-src
para src
. Depois disso, é necessário acionar o carregamento do vídeo chamando o método load
do elemento. Em seguida, a mídia vai começar a ser reproduzida automaticamente de acordo com o atributo autoplay
.
Com esse método, você tem uma solução de vídeo que emula o comportamento de GIFs animados, mas não gera o mesmo uso intensivo de dados que os GIFs animados, e é possível fazer o carregamento lento desse conteúdo.
Bibliotecas de carregamento lento
As bibliotecas a seguir podem ajudar você a carregar vídeos de forma lenta:
- vanilla-lazyload e lozad.js são opções super leves que usam apenas o Intersection Observer. Por isso, eles têm um alto desempenho, mas precisam ser preenchidos antes de serem usados em navegadores mais antigos.
- A yall.js é uma biblioteca que usa o Intersection Observer e retorna aos manipuladores de eventos. Ele também pode carregar imagens
poster
de vídeo com carregamento lento usando um atributodata-poster
. - Se você precisar de uma biblioteca de carregamento lento específica do React, considere usar a react-lazyload. Embora não use o Intersection Observer, ele oferece um método conhecido de carregamento lento de imagens para quem está acostumado a desenvolver aplicativos com o React.
Cada uma dessas bibliotecas de carregamento lento está bem documentada, com vários padrões de marcação para suas diversas iniciativas de carregamento lento.