Vídeo de carregamento lento

Assim como nos elementos de imagem, você também pode carregar vídeos de maneira lenta. Os vídeos geralmente são carregados com o elemento <video>, embora um método alternativo usando <img> tenha surgido com implementação limitada. No entanto, a forma de fazer o carregamento lento de <video> depende do caso de uso. Vamos discutir alguns cenários em que cada solução requer uma solução diferente.

Para vídeos que não são reproduzidos automaticamente

Para vídeos em que a reprodução é iniciada pelo usuário (ou seja, vídeos que não têm reprodução automática), pode ser desejável especificar o atributo preload no elemento <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>

O exemplo acima usa um atributo preload com um valor de none para evitar que os navegadores pré-carreguem quaisquer dados de vídeo. O atributo poster dá ao elemento <video> um marcador que ocupará o espaço enquanto o vídeo é carregado. O motivo é que o comportamento padrão do carregamento de vídeo pode variar de acordo com o navegador:

  • No Chrome, o padrão para preload costumava ser auto, mas, a partir do Chrome 64, o padrão agora é metadata. Mesmo assim, na versão para computador do Chrome, uma parte do vídeo pode ser pré-carregada usando o cabeçalho Content-Range. Outros navegadores baseados no Chromium e o Firefox se comportam de maneira semelhante.
  • Assim como o Chrome para computador, as versões 11.0 do Safari para computador pré-carregam vários vídeos. A partir da versão 11.2, apenas os metadados do vídeo são pré-carregados. No Safari para iOS, os vídeos nunca são pré-carregados.
  • Quando o modo Economia de dados está ativado, preload é definido como none por padrão.

Como os comportamentos padrão do navegador em relação a preload não são definitivos, a melhor opção é ser explícito. Nesses casos em que o usuário inicia a reprodução, o uso de preload="none" é a maneira mais fácil de adiar o carregamento de vídeo em todas as plataformas. O atributo preload não é a única maneira de adiar o carregamento de conteúdo em vídeo. A reprodução rápida com pré-carregamento de vídeo pode oferecer algumas ideias e insights sobre como trabalhar com a reprodução de vídeos em JavaScript.

Infelizmente, isso não é útil quando você quer usar vídeo no lugar de GIFs animados, que serão abordados a seguir.

Para vídeos que funcionam como substitutos de GIFs animados

Os GIFs animados são amplamente usados, mas são inferiores aos equivalentes em vídeo de várias maneiras, especialmente em relação ao tamanho do arquivo. Os GIFs animados podem ter vários megabytes de dados. Vídeos de qualidade visual semelhante costumam ser bem menores.

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

  1. Eles são reproduzidos automaticamente quando carregados.
  2. Elas se repetem continuamente, embora isso nem sempre seja o caso.
  3. Eles não têm faixa de áudio.

Conseguir isso com o elemento <video> fica mais ou menos assim:

<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. O playsinline é necessário para que a reprodução automática ocorra no iOS. Agora você tem um vídeo que serve como substituto do GIF e funciona em várias plataformas. Mas como fazer o carregamento lento? Para começar, modifique sua marcação <video> conforme necessário:

<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 para ocupar o espaço do elemento <video> até que o vídeo seja carregado lentamente. Assim como nos exemplos de carregamento lento de <img>, coloque o URL do vídeo no atributo data-src em cada elemento <source>. Depois, use um código JavaScript semelhante aos exemplos de carregamento lento de imagens do 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ê faz o carregamento lento de um elemento <video>, é necessário iterar todos os elementos <source> filhos e virar os atributos data-src deles para os atributos src. Depois de fazer isso, é necessário acionar o carregamento do vídeo chamando o método load do elemento. Depois disso, a mídia vai começar a ser reproduzida automaticamente de acordo com o atributo autoplay.

Ao usar esse método, você terá uma solução de vídeo que emula o comportamento do GIF animado, mas não gera o mesmo uso intensivo de dados que os GIFs animados, e você pode carregar esse conteúdo lentamente.

Bibliotecas de carregamento lento

As seguintes bibliotecas podem ajudar você a fazer o carregamento lento de vídeos:

  • vanilla-Lazyload e lozad.js são opções muito leves que usam apenas o Intersection Observer. Sendo assim, eles são de alto desempenho, mas precisarão ser polyfills antes de usá-los em navegadores mais antigos.
  • yall.js é uma biblioteca que usa Intersection Observer e volta para manipuladores de eventos. Também é possível fazer o carregamento lento de imagens poster de vídeos usando um atributo data-poster.
  • 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 vários esforços de carregamento lento.