Carregamento lento híbrido: uma migração progressiva para o carregamento lento nativo

Publicados: 2022-03-10
Resumo rápido ↬ O carregamento lento nativo está chegando à web. Como não depende de JavaScript, ele revolucionará a maneira como carregamos conteúdo com preguiça hoje, tornando mais fácil para os desenvolvedores carregar imagens e iframes com preguiça. Mas não é um recurso que podemos preencher com polyfill e levará algum tempo até que se torne utilizável em todos os navegadores. Neste artigo, você aprenderá como funciona e como pode substituir progressivamente seu carregamento lento orientado por JavaScript por sua alternativa nativa, graças ao carregamento lento híbrido.

Nas últimas semanas, você deve ter ouvido ou lido sobre o carregamento lento nativo, que está chegando ao Chromium 75 nos próximos meses.

“Sim, ótimas notícias, mas teremos que esperar até que todos os navegadores o suportem.”

Se essa foi a primeira coisa que passou pela sua cabeça, continue lendo. Vou tentar convencê-lo do contrário.

Vamos começar com uma comparação entre o carregamento lento nativo e o bom e velho baseado em JavaScript.

Carregamento lento nativo versus guiado por JavaScript

O carregamento lento é uma maneira de melhorar o desempenho de um site ou aplicativo da Web, maximizando a velocidade de renderização das imagens e iframes acima da dobra (e às vezes vídeos) adiando o carregamento do conteúdo abaixo da dobra.

Carregamento lento guiado por JavaScript

Para carregar imagens ou iframes com lentidão, é uma prática muito comum marcá-los substituindo o atributo src apropriado por um atributo de dados semelhante, data-src , e depois confiar em uma solução JavaScript para detectar quando as imagens/iframes estão recebendo perto da parte visível do site (normalmente porque o usuário rolou para baixo) e copiar os atributos de dados para os apropriados, acionando o carregamento adiado de seu conteúdo.

 <img data-src="turtle.jpg" alt="Lazy turtle" class="lazy">
Mais depois do salto! Continue lendo abaixo ↓

Carregamento lento nativo

De acordo com a especificação de carregamento lento nativo (ainda em desenvolvimento), se você deseja carregar imagens ou iframes com o recurso de carregamento lento nativo, basta adicionar o atributo loading=lazy na tag relacionada.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Addy Osmani escreveu extensivamente sobre este tópico em seu artigo “Native Image Lazy-Loading For The Web!” em que afirmou que a equipe do Google Chrome já está desenvolvendo o recurso e pretende enviá-lo no Chrome 75.

Outros navegadores baseados no Chromium, como Opera e Microsoft Edge, também se beneficiarão desse desenvolvimento, ganhando o mesmo recurso em sua primeira atualização baseada no Chromium 75.

Comece com o carregamento preguiçoso nativo

Caso as imagens do seu site sejam baixadas de uma só vez no destino da página sem carregamento lento, você pode ativar (quando suportado) o carregamento lento nativo em seu site tão facilmente quanto adicionar um atributo HTML. O atributo loading informa aos navegadores quais imagens são importantes para carregar imediatamente e quais podem ser baixadas lentamente à medida que os usuários rolam para baixo. O mesmo atributo pode ser aplicado a iframes.

Para informar aos navegadores que uma determinada imagem é importante para que eles possam carregá-la o mais rápido possível, você deve adicionar o atributo loading="eager" na tag img . A melhor prática é fazer isso para as imagens primárias — normalmente para as que serão exibidas acima da dobra.

 <img src="rabbit.jpg" alt="Fast rabbit" loading="eager">

Para informar aos navegadores que uma imagem deve ser baixada lentamente, basta adicionar o atributo loading="lazy" . Essa é uma prática recomendada apenas se você fizer isso apenas em imagens secundárias - normalmente para as que serão exibidas abaixo da dobra.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Apenas adicionando o atributo de loading às suas imagens e iframes, você permitirá que seu site use o carregamento lento nativo como um aprimoramento progressivo. Seu site se beneficiará gradualmente à medida que o suporte chegar aos seus usuários na maioria dos navegadores modernos.

Essa é a melhor abordagem a ser usada se seu site não estiver usando nenhum tipo de carregamento lento hoje, mas se você já implementou uma solução de carregamento lento orientada a JavaScript, convém mantê-la enquanto muda progressivamente para carregamento lento nativo.

A solução ideal seria começar a usar o carregamento lento nativo imediatamente e usar um polyfill para fazê-lo funcionar em todos os navegadores. Infelizmente, o carregamento lento nativo não é um recurso que podemos preencher com o JavaScript.

Não use um Polyfill

Quando uma nova tecnologia de navegador é lançada para um único navegador, a comunidade de código aberto geralmente lança um polyfill JavaScript para fornecer a mesma tecnologia para o restante dos navegadores. Por exemplo, o polyfill IntersectionObserver usa elementos JavaScript e DOM para coordenar Element.getBoundingClientRect() para reproduzir o comportamento da API nativa.

Mas o caso do carregamento lento nativo é diferente porque um polyfill JavaScript para loading="lazy" teria que impedir que os navegadores carregassem conteúdo assim que encontrassem um URL na marcação de uma imagem ou iframe. O JavaScript não tem controle sobre esse estágio inicial de renderização da página, portanto, não é possível realizar o carregamento lento nativo do polyfill.

Carregamento lento híbrido

Se você não estiver satisfeito com o carregamento lento nativo apenas como um aprimoramento progressivo, ou se já implementou o carregamento lento baseado em JavaScript e não deseja perder esse recurso em navegadores menos modernos (mas ainda deseja habilitar o carregamento lento nativo nos navegadores que o suportam), então você precisa de uma solução diferente. Apresentando: carregamento lento híbrido.

O carregamento lento híbrido é uma técnica para usar o carregamento lento nativo em navegadores que o suportam, caso contrário, conte com o JavaScript para lidar com o carregamento lento.

Para fazer o carregamento lento híbrido, você precisa marcar seu conteúdo lento usando os atributos de data em vez dos reais (como no carregamento lento controlado por JavaScript) e adicionar o atributo loading="lazy" .

 <img data-src="turtle.jpg" loading="lazy" alt="Lazy turtle">

Então você precisa de algum JavaScript. Em primeiro lugar, você precisa detectar se o carregamento lento nativo é suportado pelo navegador . Em seguida, siga um destes procedimentos para cada elemento com o atributo loading="lazy" :

  • Se o carregamento lento nativo for suportado, copie o valor do atributo data-src para o atributo src ;
  • Se não houver suporte, inicialize um script ou plug-in de carregamento lento de JavaScript para fazer isso à medida que os elementos entram na janela de visualização.

Não é muito difícil escrever o código JavaScript necessário para realizar essas operações por conta própria. Você pode detectar se o carregamento lento nativo é compatível com a condição:

 if ('loading' in HTMLImageElement.prototype)

Se for, apenas copie o valor do atributo src de data-src . Se não estiver, inicialize algum script de carregamento lento de sua escolha.

Aqui está um trecho de código que faz isso.

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <script> (function() { if ("loading" in HTMLImageElement.prototype) { var lazyEls = document.querySelectorAll("[loading=lazy]"); lazyEls.forEach(function(lazyEl) { lazyEl.setAttribute( "src", lazyEl.getAttribute("data-src") ); }); } else { // Dynamically include a lazy loading library of your choice // Here including vanilla-lazyload var script = document.createElement("script"); script.async = true; script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"; window.lazyLoadOptions = { elements_selector: "[loading=lazy]" //eventually more options here }; document.body.appendChild(script); } })(); </script>

Você pode encontrar e testar o código acima nesta demonstração ao vivo.

Ainda assim, esse é um script muito básico, e as coisas podem ficar complicadas quando você está usando atributos ou tags adicionais para obter imagens responsivas (como os atributos srcset e sizes ou mesmo as tags picture e source ).

Uma pequena ajuda de terceiros

Nos últimos quatro anos, tenho mantido um script de carregamento lento de código aberto chamado “ vanilla-lazyload ” e, alguns dias depois que Addy Osmani escreveu sobre carregamento lento nativo, a comunidade reagiu me perguntando se meu script poderia atuar como um polyfill.

Como expliquei antes, você não pode criar um polyfill para o recurso de carregamento lento nativo, no entanto, pensei em uma solução que tornaria mais fácil para os desenvolvedores iniciarem a transição para o carregamento lento nativo, sem precisar escrever nenhum código JavaScript que já mencionei antes.

A partir da versão 12 do vanilla-lazyload , você pode simplesmente definir a opção use_native como true para habilitar o carregamento lento híbrido. O script tem apenas 2,0 kB gzipado e já está disponível no GitHub, npm e jsDelivr.

  • Conheça o vanilla-lazyload no GitHub

Demonstrações

Você pode começar a brincar com o carregamento lento nativo hoje mesmo baixando o Chrome Canary ou o Microsoft Edge Insider ( canal dev ) e habilitando os sinalizadores “Ativar carregamento lento de imagem” e “Ativar carregamento lento de quadro”. Para habilitar esses sinalizadores, digite about:flags no campo de URL do seu navegador e procure por “lazy” na caixa de pesquisa.

Demonstração nativa de carregamento lento

Para analisar como o carregamento lento nativo funciona nas ferramentas do desenvolvedor, você pode começar a jogar com a demonstração a seguir. Neste, nem uma única linha de JavaScript é usada . Sim, é apenas um carregamento preguiçoso nativo completo.

  • Teste a demonstração de carregamento lento nativo

O que esperar : todas as imagens são buscadas de uma vez, mas com diferentes respostas HTTP. As com o código de resposta 200 são as imagens carregadas avidamente, enquanto as com o código de resposta 206 são apenas parcialmente buscadas para obter as informações iniciais sobre as imagens. Essas imagens serão buscadas completamente com um código de resposta de 200 quando você rolar para baixo.

Demonstração de carregamento lento híbrido

Para analisar como o carregamento lento híbrido funciona, você pode começar a jogar com a próxima demonstração. Aqui, [email protected] é usado e a opção use_native é definida como true :

  • Teste a demonstração de carregamento lento híbrido

O que esperar : Experimente a demonstração em diferentes navegadores para ver como ela se comporta. Em navegadores que suportam carregamento lento nativo, o comportamento seria o mesmo que na demonstração de carregamento lento nativo. Em navegadores que não suportam carregamento lento nativo, as imagens serão baixadas conforme você rola para baixo.

Observe que o vanilla-lazyload usa a API IntersectionObserver sob o capô, portanto, você precisaria preenchê-lo no Internet Explorer e em versões menos recentes do Safari. No entanto, não é grande coisa se um polyfill não for fornecido, porque nesse caso o vanilla-lazyload faria o download de todas as imagens de uma só vez.

Nota : Leia mais no capítulo “To Polyfill Or Not To Polyfill” do arquivo readme do vanilla-lazyload .

Experimente o carregamento preguiçoso híbrido em seu site

Como o carregamento preguiçoso nativo está chegando em breve a alguns navegadores, por que você não dá uma chance hoje usando o carregamento preguiçoso híbrido? Aqui está o que você precisa fazer:

Marcação HTML

A marcação de imagem mais simples é feita por dois atributos: src e alt .

Para as imagens acima da dobra, você deve deixar o atributo src e adicionar o atributo loading="eager" .

 <img src="important.jpg" loading="eager" alt="Important image">

Para imagens abaixo da dobra, você deve substituir o atributo src pelo atributo data data-src e adicionar o atributo loading="lazy" .

 <img data-src="lazy.jpg" loading="lazy" alt="A lazy image">

Se você quiser usar imagens responsivas, faça o mesmo com os atributos srcset e sizes .

 <img alt="A lazy image" loading="lazy" data-src="lazy.jpg">

Se você preferir usar a tag de picture , altere o srcset , sizes e src também nas tags de source .

 <picture> <source media="(min-width: 1200px)"> <source media="(min-width: 800px)"> <img alt="A lazy image" loading="lazy" data-src="lazy.jpg"> </picture>

A tag de picture também pode ser usada para carregar seletivamente o formato WebP para suas imagens.

Nota : Se você quiser saber mais usos do vanilla-lazyload , leia a seção HTML “Introdução” do arquivo leia-me.

Código JavaScript

Em primeiro lugar, você precisa incluir vanilla-lazyload em seu site.

Você pode carregá-lo de um CDN como jsDelivr:

 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Ou você pode instalá-lo usando npm:

 npm install vanilla-lazyload@12

Também é possível usar um script async com inicialização automática; carregue-o como um módulo ES usando type="module" ou carregue-o como AMD usando RequireJS. Encontre mais maneiras de incluir e usar vanilla-lazyload na seção de script “Introdução” do arquivo leia-me.

Em seguida, no código JavaScript do seu site/aplicativo da Web, inclua o seguinte:

 var pageLazyLoad = new LazyLoad({ elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading });

Nota : O script tem muitas outras configurações que você pode usar para personalizar o comportamento vanilla-lazyload , por exemplo, para aumentar a distância da área de rolagem a partir da qual começar a carregar os elementos ou para carregar elementos somente se eles permanecerem na janela de visualização por um Tempo dado. Encontre mais configurações na seção API do arquivo leia-me.

Todos juntos, usando um script async

Para juntar tudo e usar um script async para maximizar o desempenho, consulte o seguinte código HTML e JavaScript:

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <!-- Set the options for the global instance of vanilla-lazyload --> <script> window.lazyLoadOptions = { elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading }; </script> <!-- Include vanilla lazyload 12 through an async script --> <script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

É isso! Com esses passos muito simples e fáceis, você habilitará o carregamento lento híbrido em seu site!

Práticas recomendadas importantes

  • Aplique o carregamento lento apenas às imagens que você sabe que provavelmente serão exibidas abaixo da dobra. Carregue avidamente os acima da dobra para maximizar o desempenho. Se você apenas aplicar carga lenta a todas as imagens em sua página, diminuirá o desempenho de renderização.
  • Use CSS para reservar algum espaço para as imagens antes de serem carregadas. Dessa forma, eles enviarão o restante do conteúdo abaixo. Se você não fizer isso, um número maior de imagens será colocado acima da dobra antes do que deveria, acionando downloads imediatos para elas. Se você precisar de um truque de CSS para fazer isso, você pode encontrar um na seção de dicas e truques do readme do vanilla-lazyload .

Prós e contras

CARREGAMENTO LAZY NATIVO
PRÓS
  • Não requer JavaScript;
  • Sem dores de cabeça de configuração, simplesmente funciona;
  • Não há necessidade de reservar espaço para imagens usando truques de CSS;
CONTRAS
  • Não funciona hoje em todos os navegadores;
  • A carga útil inicial é maior, devido à pré-busca dos 2 kb iniciais para cada imagem.
CARREGAMENTO LAZY DRIVEN JAVASCRIPT
PRÓS
  • Ele funciona de forma consistente em todos os navegadores, agora;
  • Você pode fazer truques de interface do usuário altamente personalizados, como o efeito de desfoque ou o carregamento atrasado.
CONTRAS
  • Ele depende de JavaScript para carregar seu conteúdo.
CARREGAMENTO HÍBRIDO LAZY
PRÓS
  • Ele lhe dá a chance de habilitar e testar o carregamento lento nativo onde houver suporte;
  • Ele permite o carregamento lento em todos os navegadores;
  • Você pode remover de forma transparente a dependência de script assim que o suporte nativo ao carregamento lento for difundido.
CONTRAS
  • Ele ainda depende de JavaScript para carregar seu conteúdo.

Empacotando

Estou muito animado que o carregamento preguiçoso nativo está chegando aos navegadores e mal posso esperar para que todos os fornecedores de navegadores o implementem!

Enquanto isso, você pode optar por enriquecer sua marcação HTML para aprimoramento progressivo e obter o carregamento lento nativo somente onde houver suporte, ou você pode optar pelo carregamento lento híbrido e obter o carregamento lento nativo e orientado a JavaScript até o dia em que o carregamento lento nativo for ser suportado pela grande maioria dos navegadores.

De uma chance! Não se esqueça de estrelar/assistir vanilla-lazyload no GitHub e deixe-me saber seus pensamentos na seção de comentários.

Leitura adicional no SmashingMag:

  • Agora você me vê: como adiar, carregar lentamente e agir com o IntersectionObserver
  • Módulos JavaScript de carregamento lento com ConditionerJS
  • Lista de verificação de desempenho de front-end 2019 (PDF, Apple Pages, MS Word)
  • Como melhorar o desempenho do site pode ajudar a salvar o planeta