Lazy loading nativo de imagens e iframes é um sonho antigo de desenvolvedores web! Depois de décadas esperando por algo assim, informamos com muita felicidade que a feature está próxima de ser algo nativo nos navegadores! 😭
Para os mais afoitos, aqui está uma prévia em ação:
1 2 |
<img src="celebration.jpg" loading="lazy" alt="..." /> <iframe src="video-player.html" loading="lazy"></iframe> |
A expectativa é que o suporte para esse lazy loading nativo em imagens entre no Chrome 75. Até lá, continue lendo e veja como o lazy-loading vai funcionar.
O que é lazy loading?
Páginas web geralmente contêm um grande número de imagens, o que contribui para o uso de dados (data-usage), o aumento de páginas (page-bloat) e determinar o quão rápido uma página pode ser carregada. Muitas dessas imagens estão fora da tela, exigindo que um usuário role para visualizá-las.
Historicamente, para limitar o impacto das imagens fora da tela em tempos de carregamento da página (page load times), precisávamos usar alguma biblioteca JavaScript (como o Lozad) para adiar o carregamento dessas imagens até que o visitante rolasse a tela perto delas.
E se o navegador pudesse evitar o carregamento dessas imagens fora da tela para você, ou seja, fazer lazy loading nativo? Isso ajudaria a carregar conteúdos mais rapidamente, reduziria o uso geral de dados de rede e, em dispositivos de menor capacidade, reduziria o uso de memória.
Felizmente, depois de uma espera de décadas, em breve isso será possível com o novo atributo para lazy loading de imagens e iframes!
O atributo loading
O atributo loading
permite que um navegador adie (defer) o carregamento de imagens e iframes fora da tela (offscreen) até que o visitante role perto deles.
O novo atributo loading
admite 3 valores:
lazy
: o recurso é um bom candidato para lazy loadingeager
: não é um bom candidato para lazy loading (deve ser carregado imediatamente)auto
: o navegador determinará se deve ou não carregar usando lazy loading.
Não especificar o novo atributo terá o mesmo impacto que se loading="auto"
fosse usado. Em outras palavras, o que se está falando aqui é que lazy loading será algo nativo!
Exemplos de lazy loading nativo com o novo atributo
O atributo loading
funciona em <img>
(incluindo com srcset
e dentro de <picture>
), bem como em <iframe>
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!-- Lazy load automático de uma imagem fora da tela (offscreen) quando o scroll está perto --> <img src="unicorn.jpg" loading="lazy" alt=".."/> <!-- Carrega uma imagem imediatamente ao invés de lazy-loading --> <img src="unicorn.jpg" loading="eager" alt=".."/> <!-- O navegador decide se vai ou não usar lazy loading na imagem --> <img src="unicorn.jpg" loading="auto" alt=".."/> <!-- Lazy load de imagens em <picture> --> <picture> <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" loading="lazy"> </picture> <!-- Lazy-load em imagem com srcset especificado --> <img src="small.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(min-width: 36em) 33.3vw, 100vw" alt="A rad wolf" loading="lazy"> <!-- Lazy load em um iframe offscreen quando o scroll está próximo a ele --> <iframe src="video-player.html" loading="lazy"></iframe> |
A heurística exata para “quando o scroll está próximo” é deixada para o navegador, quer dizer, como isso vai funcionar será diferente no Chrome, Firefox, Safari etc.
Em geral, a esperança é que os navegadores comecem a carregar imagens e iframes um pouco antes de chegarem à viewport. Isso aumentará a chance da imagem ou iframe ser carregado no momento em que o usuário tiver rolado até eles.
Feature detection (detecção de recurso) para lazy loading nativo
Não há dúvidas quanto à importância de se poder carregar e aplicar uma biblioteca JavaScript para lazy loading (para suporte cross-browser). O suporte para o novo atributo loading
pode ser detectado da seguinte maneira:
1 2 3 4 5 6 7 8 |
<script> if ('loading' in HTMLImageElement.prototype) { // Se o browser suporta `loading`... } else { // Se não suporta, carrega e aplica // polyfill/biblioteca. } </script> |
Os navegadores que suportam o atributo podem obter o novo comportamento de lazy-loading com loading="lazy"
e, aqueles que ainda não oferecem suporte, continuam carregando as imagens normalmente.
Lazy loading cross browser de imagens
Se o suporte cross-browser para lazy loading de imagens é importante, não basta apenas detectar e carregar tardiamente uma biblioteca se você estiver usando <img src="unicorn.jpg" loading="lazy" />
na marcação.
A marcação precisa usar algo como <img data-src="unicorn.jpg" />
(em vez de src
, srcset
ou <source>
) para evitar o acionamento eager
em navegadores que não suportam o novo atributo.
JavaScript pode ser usado para alterar esses atributos para os corretos se lazy loading de imagem e iframe for suportado e, caso não, carregar uma biblioteca no lugar.
Seria algo mais ou menos como:
- Imagens na viewport ou acima da dobra são tags
<img>
regulares. Umdata-src
iria ter prioridade sobre o “preload scanner”, o que deve ser evitado para tudo que provavelmente estiver na viewport. - Usa-se
data-src
em imagens para evitar um carregamento “eager” em navegadores não suportados. Se o carregamento for suportado, troca-sedata-src
porsrc
. - Se o novo atributo
loading
não for suportado, carrega-se um fallback (que é iniciado imediatamente).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<!-- Imagem "in-viewport" normal --> <img src="hero.jpg" alt="..." /> <!-- Lazy load para o resto das imagens --> <img data-src="unicorn.jpg" loading="lazy" alt=".." class="lazyload"/> <img data-src="cats.jpg" loading="lazy" alt=".." class="lazyload"/> <img data-src="dogs.jpg" loading="lazy" alt=".." class="lazyload"/> <script> (async () => { const images = document.querySelectorAll("img.lazyload"); if ('loading' in HTMLImageElement.prototype) { images.forEach(img => { img.src = img.dataset.src; }); } else { // Importa dinamicamente uma biblioteca para lazy loading. // Neste exemplo, lazySizes, mas poderia ser qualquer outra. const lazySizesLib = await import('/lazysizes.min.js'); // Inicializa LazySizes (lê data-src & class=lazyload) lazySizes.init(); } })(); </script> |
Para usar lazy loading de imagens agora (se você usa Chrome), acesse chrome://flags
e habilite ambos, “Enable lazy frame loading” e “Enable lazy image loading”, então reinicie o Chrome.
Conclusão sobre lazy loading nativo de imagens e iframes
Um dos sonhos de ouro de desenvolvedores web, principalmente os mais ligados à performance, era passar por essa vida podendo usar lazy loading nativo de imagens. Felizmente, o sonho agora vai se tornar realidade muito em breve!
Carregar via lazy-loading imagens e iframes será o novo padrão da Web, o que trará imensas vantagens para todos, desenvolvedores e seres humanos normais.
Agora vai!