
As imagens estão entre os conteúdos mais presentes na web, e o tempo de carregamento das páginas torna-se depressa um problema.
Mesmo bem otimizadas, as imagens continuam a pesar. Isso alonga a espera antes de o visitante chegar ao conteúdo do site. Há boas hipóteses de ele se impacientar e ir para outro lado, a menos que encontres uma forma de carregar as imagens que não interfira com a velocidade percebida.
Neste artigo vais descobrir cinco abordagens de lazy loading das imagens para juntares à tua caixa de ferramentas de otimização web e melhorares a experiência no teu site.
O que é o lazy loading?
O lazy loading das imagens consiste em carregá-las de forma assíncrona, ou seja, depois do conteúdo que vem antes, ou até sob condição, apenas quando aparecem na janela do navegador. Isto significa que, se o utilizador não descer a página, as imagens colocadas no fundo nem sequer chegam a ser carregadas.
Vários sites usam esta abordagem, mas ela nota-se sobretudo nos sites com muitas imagens. Percorre o teu banco preferido de fotografias em alta resolução e vais reparar depressa que o site só carrega um número limitado de imagens. À medida que desces, os marcadores de posição enchem-se rapidamente com as imagens reais da pré-visualização. Repara, por exemplo, no carregamento em Unsplash.com: fazer aparecer essa parte da página desencadeia a substituição do marcador por uma fotografia em resolução completa.
Porquê interessares-te pelo lazy loading das imagens?
Há pelo menos duas boas razões para usares imagens em lazy loading no teu site:
- Se o teu site usa JavaScript para mostrar conteúdo ou para oferecer uma funcionalidade qualquer, o carregamento do DOM torna-se depressa crítico. É comum os scripts esperarem que o DOM esteja completamente carregado antes de começarem a correr. Num site com um número considerável de imagens, o lazy loading – o carregamento assíncrono das imagens – pode fazer a diferença entre o visitante que fica e o que abandona o teu site.
- Como a maioria das soluções de lazy loading só carrega as imagens se o utilizador descer até ao ponto em que elas ficariam visíveis na janela de visualização, essas imagens nunca chegam a ser carregadas se ele nunca lá chegar. Isso representa uma poupança considerável de largura de banda, que a maioria dos utilizadores – sobretudo os que navegam em telemóvel e em ligações lentas – te vai agradecer.
O lazy loading das imagens contribui para o desempenho de um site, mas qual é a melhor forma de o fazer?
Não existe método perfeito.
Se vives e respiras JavaScript, escrever a tua própria solução de lazy loading não te vai levantar problemas. Nada dá mais controlo do que o código feito por ti.
Também podes vasculhar a web à procura de abordagens viáveis e começar a experimentá-las. Foi o que fiz, e encontrei estas cinco técnicas interessantes.
#1 Lazy loading nativo
O lazy loading nativo das imagens e das iframes é muito prático. Nada podia ser mais simples do que a marcação abaixo:
<img src="myimage.jpg" loading="lazy" alt="..." />
<iframe src="content.html" loading="lazy"></iframe>
Como podes ver, não há JavaScript nem troca dinâmica do src das imagens e das iframes: é bom e velho HTML.
O atributo loading permite adiar as imagens e as iframes fora do ecrã até o utilizador descer até ao sítio que ocupam na página. O loading aceita um destes três valores:
lazy: funciona muito bem para o lazy loadingeager: pede ao navegador que carregue imediatamente o conteúdo indicado.auto: deixa ao navegador a decisão de aplicar ou não o lazy loading.
Este método não tem rival: nenhum custo adicional, limpo e simples. Ainda assim, mesmo que à data em que escrevemos a maioria dos grandes navegadores já tenha um bom suporte do atributo loading, nem todos vão a bordo.
#2 Lazy loading com a API Intersection Observer
A API Intersection Observer é uma interface moderna que podes usar para aplicar lazy loading a imagens e a outros conteúdos.
Eis como a MDN apresenta esta API:
A API Intersection Observer permite observar de forma assíncrona as mudanças na interseção de um elemento alvo com um elemento antecessor ou com a janela de visualização de um documento de nível superior.
Por outras palavras, o que se observa de forma assíncrona é a interseção de um elemento com outro.
Imagina que queres aplicar lazy loading a uma galeria de imagens. A marcação de cada imagem ficaria assim:
<img data-src="image.jpg" alt="test image">
Repara que o caminho da imagem está num atributo data-src e não num atributo src. A razão é simples: com src, a imagem carregaria de imediato, que é precisamente o que não queres.
No CSS, dás a cada imagem uma min-height, digamos 100px. Assim cada lugar de imagem (o elemento img sem o atributo src) fica com uma dimensão vertical:
img {
min-height: 100px;
/* mais estilos aqui */
}
No ficheiro JavaScript, crias depois um objeto config e registas com ele uma instância de intersectionObserver:
// criar um objeto de configuração: rootMargin e threshold
// são duas propriedades expostas pela interface
const config = {
rootMargin: '0px 0px 50px 0px',
threshold: 0
};
// registar o objeto config com uma instância
// de intersectionObserver
let observer = new intersectionObserver(function(entries, self) {
// iterar sobre cada entrada
entries.forEach(entry {
// tratar apenas as imagens em interseção.
// isIntersecting é uma propriedade exposta pela interface
if(entry.isIntersecting) {
/. / Fonction personnalisée qui copie le chemin vers l'image
// de data-src para src
preloadImage(entry.target);
// a imagem já está no sítio, deixar de observar
self.unobserve(entry.target);
}
});
}, config);
Por fim, percorres todas as imagens e acrescentas cada uma a essa instância de iterationObserver:
const imgs = document.querySelectorAll('[data-src]');
imgs.forEach(img {
observer.observe(img);
});
As vantagens desta solução: monta-se sem esforço, é eficaz e deixa o intersectionObserver encarregar-se do trabalho pesado dos cálculos.
Em contrapartida, embora a API Intersection Observer esteja disponível na maioria dos navegadores nas suas versões recentes, não é suportada de forma sistemática por todos. Felizmente, existe um polyfill disponível.
#3 Lozad.js – lazyload js
Uma alternativa rápida e simples para implementar o lazy loading das imagens é deixar uma biblioteca JS fazer o trabalho pesado por ti.
O Lozad é um carregador lazy muito eficiente, leve e configurável, escrito em JavaScript puro e sem qualquer dependência. Serve para aplicar lazy loading a imagens, vídeos, iframes e muito mais, e assenta na API Intersection Observer.
Podes instalar o Lozad com npm/Yarn e importá-lo com o module bundler que preferires:
npm install --save lozad
yarn add lozad
import lozad from 'lozad';
Também podes carregar a biblioteca a partir de um CDN e acrescentá-la ao fundo da página HTML numa tag < script>:
<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
A seguir, para uma implementação básica, acrescenta a classe lozad ao elemento na tua marcação:
<img class="lozad" data-src="img.jpg">
Por fim, instancia o Lozad no teu ficheiro JS:
const observer = lozad();
observer.observe();
Todos os detalhes de utilização da biblioteca estão no repositório GitHub do Lozad.
Se não te apetece mergulhar nos meandros da API Intersection Observer, ou se procuras apenas uma implementação rápida que sirva para vários tipos de conteúdo, o Lozad é uma excelente escolha.
Só atenção ao suporte dos navegadores: se for preciso, junta-lhe um polyfill para a API Intersection Observer.
#4 Lazy loading com efeito de imagem desfocada
A primeira coisa que vês é uma cópia desfocada e em baixa resolução da imagem, enquanto a versão em alta resolução é carregada em lazy loading:


Podes aplicar lazy loading às imagens com este efeito de desfoque de várias maneiras.
Eis todas as vantagens desta solução:
- Desempenho: apenas 463 bytes de CSS e 1 007 bytes de JavaScript minificado.
- Suporte dos ecrãs retina
- Sem dependências: não é preciso jQuery nem outras bibliotecas ou frameworks.
- Melhoria progressiva, para responder aos navegadores mais antigos e ao JavaScript que falha.
Para obteres este tipo de efeito, podes descarregar o progressive-image.js.
#5 Yall.js – lazyload js
O Yall é um script de lazy loading completo para imagens, vídeos e iframes. Assenta na API Intersection Observer e recorre de forma inteligente às técnicas clássicas de gestão de eventos quando é preciso.
Depois de incluíres o Yall no teu documento, tens de o inicializar assim:
<script src="yall.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", yall);
</script>
A seguir, para aplicares lazy loading a uma simples img, tudo o que precisas de fazer na tua marcação é isto:
<img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image.">
Repara no seguinte:
- acrescentas a classe Lazyload ao elemento
- o valor de
srcé uma imagem de substituição - o caminho da imagem a carregar em lazy loading está no atributo
data-src
Entre as vantagens do Yall contam-se:
- grande desempenho graças à API Intersection Observer
- suporte de navegadores fantástico (recua até ao IE11)
- nenhuma outra dependência necessária
Para saberes mais sobre o que o Yall oferece e para implementações mais complexas, vê a página no GitHub.
Conclusão
Aqui tens: cinco métodos de lazy loading das imagens para começares a experimentar e a testar nos teus projetos.


