Adiar Imagens Fora da Tela no Mobile: Guia de Lazy Loading Nativo

Lazy loading nativo, content-visibility e por que o adiamento de imagens com JavaScript é um peso morto

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-10

Adiamento de Imagens no Mobile: o padrão

Páginas mobile lutam por conexões limitadas e CPU limitada. Cada imagem fora da tela que você carrega antecipadamente rouba largura de banda das imagens e scripts que realmente importam para a renderização inicial.

Última revisão por Arjen Karel em março de 2026

1. Adiar imagens fora da tela no mobile: lazy loading nativo

Quando um navegador carrega uma página, ele abre um número limitado de conexões paralelas (dependendo de muitos fatores, mas 6 por domínio é uma média comum). Se essas conexões forem usadas para baixar imagens fora da tela (ex., um logotipo no rodapé ou slide de carrossel), o download de recursos críticos (tipicamente a imagem do LCP, scripts e fontes importantes) competirá por slots e largura de banda. Isso é contenção de rede e degrada diretamente os seus Core Web Vitals.

Ao adiar imagens fora da tela usando o atributo nativo loading, você prioriza o que importa. O navegador busca apenas o que é imediatamente visível, reservando largura de banda para os ativos que impactam o Largest Contentful Paint (LCP) e o First Contentful Paint (FCP). O lazy loading nativo transfere essa priorização para o próprio mecanismo do navegador, o que é mais rápido e remove a necessidade de bibliotecas de lazy loading em JavaScript.

Implementação

Para todas as imagens abaixo da viewport inicial ("the fold"), adicione o atributo loading="lazy".

<!-- Imagem Adiada Padrão -->
<img src="product-detail.jpg"
     loading="lazy"
     alt="Vista lateral do chassi"
     width="800"
     height="600"
     decoding="async">

Os atributos width e height são essenciais. Sem eles, o navegador não consegue reservar espaço antes da imagem carregar, o que causa layout shift (CLS). 62% das páginas mobile ainda falham em definir dimensões explícitas em pelo menos uma imagem.

Como o lazy loading funciona no mobile: A Heurística do Navegador

O lazy loading nativo é superior às soluções em JavaScript porque o navegador ajusta o limite de carregamento (quando o download de uma imagem é acionado) com base no Effective Connection Type (ECT).

  • No 4G/WiFi: O motor Blink (Chrome/Edge) usa um limite conservador de cerca de 1.250px. Ele assume baixa latência e busca a imagem apenas quando o usuário rola relativamente perto.
  • No 3G/Slow-2G: O limite se expande para cerca de 2.500px. O navegador inicia a requisição muito mais cedo para compensar os altos tempos de ida e volta, para que a imagem esteja pronta antes de o usuário rolar para visualizá-la.

De acordo com o Web Almanac 2025, a página mobile mediana carrega 15 imagens totalizando 911 KB. Apenas cerca de 26% dessas imagens usam loading="lazy". O restante carrega de forma ávida (eager), competindo pelas mesmas conexões limitadas. Em uma conexão mobile 4G típica, isso significa que a imagem do LCP fica presa esperando atrás de uma dúzia de imagens que o usuário não verá por vários segundos.

Exceção Crítica: O Candidato a LCP

Uma regressão de desempenho comum: aplicar loading="lazy" ao elemento do Largest Contentful Paint (tipicamente a hero image). Isso atrasa a busca até que o layout esteja completo.

A pesquisa do Google mostra que fazer lazy loading da imagem do LCP adiciona 624ms ao LCP mediano. Isso não é um risco teórico. 17% das páginas mobile ainda cometem esse erro de acordo com o Web Almanac 2025. Se o Lighthouse sinalizar isso, veja como corrigir o aviso de LCP com lazy loading.

A imagem do LCP deve ser carregada de forma ávida (eager) e priorizada:

<!-- Hero Image: Ávida e Priorizada -->
<img src="hero.jpg"
     alt="Coleção de Verão"
     width="1200"
     height="800"
     loading="eager"
     fetchpriority="high">

Não combine loading="lazy" com fetchpriority="high". Eles se contradizem: lazy diz ao navegador para esperar, high diz para se apressar. O navegador ignora a dica de prioridade quando lazy está definido. Para mais informações sobre como os navegadores priorizam recursos, veja o guia de priorização de recursos.

2. Complexidades do mobile: Viewport e Touch

As viewports mobile não são estáticas. A área visível muda conforme o usuário rola, gira o dispositivo ou faz com que a barra de URL se retraia. É aqui que o lazy loading nativo tem uma vantagem real sobre as soluções em JavaScript.

  • A Viewport: A área retangular visível da janela do navegador. No mobile, isso é dinâmico; ela muda de dimensões com base na orientação do dispositivo (retrato vs. paisagem) e no estado da interface do navegador (barras de URL se retraindo).
  • The Fold (A Dobra): A borda inferior exata da viewport. É o limite que separa o conteúdo visível do conteúdo fora da tela.
  • Above the Fold (Acima da Dobra): Qualquer conteúdo visível imediatamente no carregamento da página sem rolar. As imagens aqui são críticas e nunca devem usar lazy loading.
  • Below the Fold (Abaixo da Dobra): Qualquer conteúdo localizado verticalmente após a dobra. Esse conteúdo não é crítico e deve ser adiado até que o usuário role perto dele.

A Viewport Dinâmica

Em navegadores mobile, a altura da viewport (vh) é fluida. Conforme o usuário inicia uma rolagem por toque (touch scroll), a barra de URL e os controles de navegação frequentemente se retraem, mudando o tamanho da área visível.

As bibliotecas de lazy loading em JavaScript normalmente calculam a altura da viewport (window.innerHeight) uma vez no carregamento da página. Quando os navegadores mobile redimensionam dinamicamente a área visível ocultando a barra de URL durante uma rolagem, os métodos em JavaScript continuam a usar o valor antigo e menor de altura. As imagens permanecem descarregadas mesmo quando entram na viewport expandida, causando espaços em branco (placeholders) para os visitantes.

O mecanismo de layout interno do navegador rastreia a viewport visual automaticamente, para que os gatilhos do lazy loading nativo disparem independentemente das mudanças de tamanho da viewport. Esta é uma razão para preferir o lazy loading nativo em vez de qualquer alternativa em JavaScript.

3. Decodificação de Imagens no Mobile e Limitação de CPU

Dispositivos mobile têm CPU limitada e a decodificação de imagens no mobile pode ser relativamente lenta e cara. Converter um JPEG em um bitmap requer muitos ciclos de CPU. Em um processador mobile, decodificar uma sequência de imagens maiores pode bloquear a main thread por 50ms a 100ms cada, causando latência de entrada.

A Solução: content-visibility

A propriedade CSS content-visibility: auto age como lazy rendering. Ela instrui o navegador a ignorar completamente as fases de layout e pintura para elementos fora da tela. O elemento existe no DOM, mas não existe na Árvore de Renderização (Render Tree) até se aproximar da viewport.

Como essa otimização funciona pulando a renderização da subárvore de um elemento, você não pode aplicá-la diretamente a uma tag <img> (que não possui subárvore). Aplique content-visibility ao contêiner do produto ou cartão de imagem que hospeda as imagens e seu conteúdo:

@media (max-width: 768px) {
    .image-card, .product-card {
        /* Pula a renderização do contêiner e de seus filhos */
        content-visibility: auto;

        /* Essencial: Evita que o contêiner colapse para 0px de altura */
        contain-intrinsic-size: auto 300px;
    }
}

Isso garante que, mesmo que uma imagem seja baixada, o navegador não pague o custo de layout/pintura até que o usuário realmente role até ela.

O content-visibility alcançou o status de Baseline em setembro de 2024, quando o Safari 18 lançou o suporte. Ele agora funciona em 93% dos navegadores globalmente. Os benchmarks do Google mostram um aumento de 7x no desempenho de renderização no carregamento inicial para páginas com muitas seções fora da tela.

Se você quiser verificar a melhoria de renderização em dispositivos reais, o Real User Monitoring mostrará o impacto real do INP e LCP em seu tráfego mobile. Em sites monitorados pelo CoreDash, páginas que usam content-visibility: auto em grades de produtos mostram um INP cerca de 15% melhor no mobile em comparação com páginas sem ele.

4. Metodologias Legadas: Por que evitá-las

Antes que loading="lazy" tivesse suporte nos navegadores, o JavaScript era a única opção. Com o lazy loading nativo com 95% de suporte global, esses métodos em JavaScript são dívida técnica. Remova-os.

A Era do Manipulador de Rolagem (2010 a 2016)

As primeiras implementações anexavam ouvintes de eventos ao evento de rolagem (scroll).

// Obsoleto: não use
window.addEventListener('scroll', () => {
    images.forEach(img => {
        if (img.getBoundingClientRect().top < window.innerHeight) {
            img.src = img.dataset.src;
        }
    });
});

Bloqueio da Main Thread: O evento de rolagem dispara dezenas de vezes por segundo. Executar lógica e calcular o layout (getBoundingClientRect) durante a rolagem ativa causa quedas de quadros (jank).

Layout Thrashing: Consultar propriedades geométricas força o navegador a recalcular o layout de forma síncrona, uma operação computacionalmente cara em CPUs mobile.

A Era do IntersectionObserver (2016 a 2019)

A API IntersectionObserver melhorou o desempenho observando as mudanças na visibilidade do elemento de forma assíncrona.

// Legado: prefira loading="lazy" nativo onde possível
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            observer.unobserve(img);
        }
    });
});

Dependência de Script: Requer execução de JavaScript. Se a main thread estiver ocupada hidratando um framework (React/Vue), as imagens permanecem descarregadas mesmo que estejam na viewport.

Falta de Consciência de Rede: Ao contrário do carregamento nativo, o IntersectionObserver usa margens fixas (ex., rootMargin: '200px'). Ele não expande automaticamente seu buffer em redes lentas, levando a flashes em branco para usuários em conexões ruins.

Para uma visão geral completa das técnicas de otimização de imagens além do lazy loading, ou para aprender sobre como adiar imagens de fundo CSS (o que o loading="lazy" não cobre), consulte esses guias dedicados.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

I have done this before at your scale.

Complex platforms, large dev teams, legacy code. I join your team as a specialist, run the performance track, and hand it back in a state you can maintain.

Discuss Your Situation
Adiar Imagens Fora da Tela no Mobile: Guia de Lazy Loading NativoCore Web Vitals Adiar Imagens Fora da Tela no Mobile: Guia de Lazy Loading Nativo