Vídeo de carregamento lento

Publicado em 16 de agosto de 2019. Última atualização: 2 de julho de 2026

Assim como os elementos de imagem, talvez você queira 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 em iframes de carregamento lento.

O carregamento lento de <video> depende do caso de uso, já que há algumas soluções diferentes.

Como usar o atributo loading

Os navegadores começaram a oferecer suporte ao atributo loading em elementos de mídia (<video> e <audio>). Quando há suporte, isso significa que a mídia e qualquer imagem de pôster são carregadas de forma lenta automaticamente apenas adicionando o atributo loading="lazy":

<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>

O uso de loading="lazy" impede que a imagem poster seja carregada até estar na janela de visualização ou perto dela. Depois, o atributo preload é usado para decidir quanto do video carregar. Isso também significa que os vídeos autoplay não serão reproduzidos automaticamente até estarem na janela de visualização ou perto dela. O atributo loading="lazy" funciona com os atributos poster, preload e autoplay, mas não os substitui.

Os navegadores que não são compatíveis com o atributo loading em elementos de mídia vão ignorá-lo. Isso fará com que a imagem poster seja carregada imediatamente e o vídeo seja carregado com base no atributo preload, que vamos abordar a seguir.

Use o atributo preload para carregar lentamente vídeos que não são reproduzidos automaticamente

Evitar a reprodução automática de vídeos geralmente é uma prática recomendada, já que deixa o controle com o usuário. Nesses casos, especificar o atributo preload no elemento <video> é a melhor maneira de evitar o carregamento do vídeo inteiro até que ele seja necessário:

<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>

O exemplo anterior usa um atributo preload com um valor de none para impedir que os navegadores pré-carreguem qualquer dado de vídeo, mesmo quando estiverem na janela de visualização. 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, preload é definido como metadata por padrão, 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. Os navegadores não sabem em quais bytes os metadados estão armazenados, e eles podem não estar no início do arquivo. Portanto, a melhor maneira de evitar o carregamento do vídeo é usar o 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
  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>

Isso não apenas reduz o atraso quando o usuário vai reproduzir o vídeo, mas também mostra a duração dele assim que o usuário.

Os vídeos podem se qualificar como candidatos a LCP. Uma imagem poster carrega mais rápido do que o vídeo. Portanto, quando ela for uma candidata a LCP, use uma imagem de pôster, mas também faça o pré-carregamento com um valor de atributo fetchpriority de "high", já que no momento da escrita, não é possível especificar o fetchpriority para atributos de pôster:

<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>

Os vídeos que são elementos de LCP não devem usar loading="lazy", da mesma forma que você não deve carregar imagens de LCP de forma lenta .

Para vídeos que substituem GIFs animados

Os vídeos de reprodução automática são usados com frequência para animações rápidas no estilo GIF. Embora os GIFs animados sejam amplamente usados, eles são inferiores aos equivalentes em vídeo de várias maneiras, principalmente em tamanho de arquivo. GIFs animados podem ter vários megabytes de dados. Vídeos com qualidade visual semelhante tendem a ser muito menores.

Usar o elemento <video> como substituto de um GIF animado não é tão simples quanto o elemento <img>. Os GIFs animados têm três características:

  1. Eles são reproduzidos automaticamente quando carregados.
  2. Elas ficam em loop contínuo (mas nem sempre é assim).
  3. Não têm 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>

O atributo loading="lazy" evita o carregamento do vídeo até que ele esteja perto da janela de visualização. 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 um substituto funcional para vídeo como GIF que funciona em todas as plataformas. Mas como fazer o carregamento lento?

Para navegadores compatíveis, a opção mais fácil é loading="lazy":

<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>

Para oferecer suporte ao carregamento lento de vídeo em outros navegadores, use JavaScript e modifique a marcação <video> de acordo com o seguinte:

<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>

Você vai notar a remoção de autoplay e a adição dos atributos class="lazy", preload="none" e poster, que permitem especificar um marcador de posição para ocupar o espaço do elemento <video> até que o vídeo seja carregado de forma lenta. Em seguida, usamos um observador de interseção do JavaScript para reativar a reprodução automática:

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);
    });
  }
});

Com esse método, o vídeo não é reproduzido automaticamente por padrão, apenas quando o observador de interseção detecta que ele está entrando na janela de visualização. Além disso, o atributo controls processa os casos em que o JavaScript falha. Isso significa que você tem uma solução de vídeo que emula o comportamento de GIFs animados, mas não incorre no mesmo uso intensivo de dados que eles, e você pode carregar esse conteúdo de forma lenta.

Bibliotecas de carregamento lento

As seguintes bibliotecas podem ajudar você a carregar vídeos de forma lenta:

  • vanilla-lazyload e lozad.js são opções superleves que usam apenas o Intersection Observer. Por isso, eles têm alta performance, mas precisam ser preenchidos com polyfill antes de serem usados em navegadores mais antigos.
  • Se você precisar de uma biblioteca de carregamento lento específica do React, considere usar react-lazyload. Embora não use o Intersection Observer, ele fornece 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 é bem documentada, com muitos padrões de marcação para suas várias iniciativas de carregamento lento.

À medida que o atributo loading para <video> ficar disponível em mais navegadores, esperamos que as soluções JavaScript (incluindo bibliotecas) sejam menos usadas em favor das soluções integradas, exceto para quem quer mais controle do que isso permite.