Vídeo de carregamento lento

Assim como nos elementos de imagem, você também pode fazer o carregamento lento de vídeos. 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 carregar <video> lentamente depende do caso de uso. Vamos discutir alguns cenários em que cada um 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 são reproduzidos automaticamente), especifique 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 fornece ao elemento <video> um marcador que ocupará o espaço enquanto o vídeo é carregado. O motivo é que os comportamentos padrão de carregamento de vídeo podem variar de acordo com o navegador:

  • No Chrome, o padrão de preload era auto, mas, a partir do Chrome 64, será definido como 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 comportam-se de forma semelhante.
  • Assim como no Chrome para computadores, as versões 11.0 para computador do Safari pré-carregam uma parte do vídeo. 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 de Economia de dados está ativado, preload é definido por padrão como none.

Como o comportamento padrão do navegador em relação a preload não é inflexível, ser explícito é provavelmente a melhor opção. 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ídeos em todas as plataformas. O atributo preload não é a única maneira de adiar o carregamento de conteúdo de vídeo. Reprodução rápida com pré-carregamento de vídeo pode oferecer algumas ideias e insights sobre como trabalhar com reprodução de vídeo em JavaScript.

Infelizmente, isso não é útil para usar vídeos em vez de GIFs animados, que serão abordados a seguir.

Para vídeos que substituem GIFs animados

Embora os GIFs animados sejam bastante usados, eles 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 tendem a ser bem 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. Eles são repetidos continuamente (embora esse nem sempre seja o caso).
  3. Eles não têm faixa de áudio.

Conseguir isso com o elemento <video> vai ficar 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 como substituto do GIF que funciona em várias plataformas. Mas como fazer o carregamento lento? Para começar, modifique a marcação <video> conforme indicado:

<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 lentamente. Assim como nos exemplos de carregamento lento de <img>, armazene o URL do vídeo no atributo data-src em cada elemento <source>. A partir daí, use um código JavaScript semelhante aos exemplos de carregamento lento de imagem baseados 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);
    });
  }
});

Ao fazer o carregamento lento de um elemento <video>, você precisa iterar todos os elementos <source> filhos e inverter os atributos data-src em 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.

Usando 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. 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 super leves que usam apenas Intersection Observer. Por isso, eles têm alto desempenho, mas precisam ser polyfill antes de serem usados em navegadores mais antigos.
  • yall.js é uma biblioteca que usa Intersection Observer e retorna para manipuladores de eventos. Ela também pode fazer o carregamento lento de imagens poster de vídeo usando um atributo data-poster.
  • Se você precisar de uma biblioteca de carregamento lento específica do React, considere usar o react-Lazyload. Embora não use o Intersection Observer, ele fornece um método familiar 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 seus vários esforços de carregamento lento.