Página que pula quando a imagem carrega: width, height e o arquivo do tamanho certo
Reserve o espaço de cada imagem com width e height ou aspect-ratio, sirva arquivos perto do tamanho exibido e use lazy loading só onde ajuda.
A pessoa vai tocar em "Ver detalhes" no celular, a foto do produto termina de carregar acima do botão, empurra tudo 280 pixels para baixo e o dedo acerta o anúncio. Ela não volta. A resposta curta: declare width e height em toda img, com as dimensões reais do arquivo, e use max-width: 100%; height: auto no CSS. O navegador calcula a proporção antes de baixar a imagem e reserva o retângulo certo. Depois, sirva um arquivo perto do tamanho mostrado e não aplique carregamento preguiçoso na imagem principal do topo.
Esse pulo tem nome nas métricas do Google: CLS, Cumulative Layout Shift. Para ser considerado bom, ele deve ficar em 0,1 ou menos. Imagem sem dimensão é uma das causas mais comuns de passar disso.
Por que o texto desce quando a foto chega
O navegador monta a página à medida que o HTML chega. Quando encontra uma img sem tamanho, ele não sabe quanto espaço ela vai ocupar, então reserva zero de altura e continua desenhando o texto logo abaixo. Quando os primeiros bytes da imagem chegam, ele descobre as dimensões, abre o espaço e empurra o resto da página. Em rede rápida isso dura um instante. Em 4G fraco, dura o suficiente para a pessoa já ter começado a ler ou a tocar.
Os navegadores atuais usam os atributos width e height para calcular a proporção da imagem antes de ela chegar. Com height: auto no CSS, a imagem continua responsiva: a largura acompanha o contêiner e a altura reservada segue a proporção declarada. Por isso os atributos voltaram a ser recomendados, mesmo em layouts fluidos.
O segundo problema é o peso. No nosso exemplo, a loja mostra cards de 400 pixels de largura com fotos de 4000 por 3000 pixels, 2,8 MB cada. Doze cards na listagem somam mais de 30 MB. A página fica lenta, o pulo dura mais e o plano de dados da pessoa paga a conta.
Como reservar o espaço e servir o tamanho certo
- Coloque
widtheheightem todas as imagens, com as dimensões do arquivo ou qualquer par com a mesma proporção. - Garanta a regra de CSS responsiva para que os atributos não fixem o tamanho em pixels na tela.
- Para imagens com recorte, defina
aspect-rationo contêiner e useobject-fit: coverna imagem. - Gere versões redimensionadas do arquivo original, perto da largura exibida e do dobro dela para telas de alta densidade.
- Use
srcsetesizespara o navegador escolher a versão adequada. - Aplique
loading="lazy"nas imagens abaixo da primeira dobra, e nunca na imagem principal do topo. - Meça com rede lenta simulada e confira se ainda há deslocamento.
O HTML e o CSS do card
<article class="card">
<img
src="/img/tenis-azul-800.webp"
srcset="/img/tenis-azul-400.webp 400w, /img/tenis-azul-800.webp 800w"
sizes="(max-width: 600px) 100vw, 400px"
width="800" height="600"
alt="Tênis de corrida azul com sola branca, vista lateral"
loading="lazy" decoding="async">
<h2>Tênis Corrida Leve</h2>
<p>R$ 299,90</p>
</article>
img {
max-width: 100%;
height: auto;
}
Os atributos width="800" height="600" dizem a proporção 4:3. Com a regra de CSS, o card de 400 pixels reserva 300 de altura antes do primeiro byte. O srcset lista duas versões com a largura real de cada uma, e o sizes diz ao navegador quanto da tela a imagem ocupa: a largura toda em telas até 600 pixels, 400 pixels nas maiores. Com isso, um celular com densidade 2 e tela de 390 pixels escolhe a versão de 800; um monitor comum escolhe a de 400. O texto alternativo segue o que está em texto alternativo descreve a imagem.
Imagem com recorte fixo
Quando o design pede que todas as fotos da grade tenham a mesma proporção, mesmo que os arquivos variem, reserve o espaço no CSS:
.card img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
A propriedade aspect-ratio garante o retângulo, e object-fit: cover recorta a imagem para preencher sem distorcer.
Como gerar as versões menores
Com ImageMagick 7, o comando magick redimensiona mantendo a proporção quando você informa só a largura:
magick tenis-azul.jpg -resize 800x -quality 80 tenis-azul-800.webp
magick tenis-azul.jpg -resize 400x -quality 80 tenis-azul-400.webp
No exemplo, a versão de 800 pixels ficou com cerca de 70 KB contra os 2,8 MB do original. O número exato depende da foto, mas a ordem de grandeza costuma ser essa. Se o upload vem do usuário, gere essas versões no servidor no momento do envio, como mostrado em redimensionar imagem no servidor.
Onde o lazy loading ajuda e onde atrapalha
O atributo loading="lazy" faz o navegador adiar o download de imagens fora da tela até que a pessoa role perto delas. Na listagem de doze cards, as oito de baixo não precisam chegar antes do texto. Isso economiza banda e libera a rede para o que importa primeiro.
Na imagem principal do topo, por exemplo a foto grande da página de produto, o efeito é o contrário: ela só começa a baixar depois que o navegador calcula o layout e confirma que está visível. Essa imagem costuma ser o maior elemento da tela, medido pela métrica LCP. Deixe-a com carregamento normal e, se quiser priorizar, use fetchpriority="high". O post site mais rápido: por onde começar coloca essa escolha no contexto das outras otimizações.
Como ver o pulo acontecer
No Chrome, abra as ferramentas de desenvolvedor, limite a rede a uma conexão lenta na aba Network e recarregue. Na gaveta Rendering, ative a opção que destaca regiões de deslocamento de layout: cada pulo pisca em azul. O Lighthouse e o painel Performance mostram o valor de CLS e apontam os elementos que mais se moveram. Para dados de visitantes reais, o relatório de Core Web Vitals do Search Console agrupa as páginas por situação.
Erros comuns
- Imagem sem
widtheheight. O navegador reserva zero de altura e empurra o conteúdo quando ela chega. - Atributos com proporção diferente do arquivo. O espaço reservado não bate com a imagem e o pulo acontece mesmo assim, ou a imagem aparece distorcida.
- Atributos sem
height: autono CSS. A imagem fica presa ao tamanho em pixels e transborda em telas estreitas. - Arquivo de 4000 pixels num card de 400. A página pesa dezenas de megabytes e demora mais para estabilizar.
- Lazy loading na imagem principal do topo. O maior elemento da tela chega por último e a página parece mais lenta.
- Testar só no Wi-Fi do escritório. O pulo dura milissegundos ali e passa despercebido; no celular da pessoa, dura segundos.
Checklist
- Toda
imgtemwidtheheightcom a proporção real do arquivo. - O CSS global tem
max-width: 100%eheight: autopara imagens. - Grades com recorte usam
aspect-ratioeobject-fit. - Cada imagem tem versões próximas da largura exibida e do dobro dela.
srcsetesizesestão declarados nas imagens de conteúdo.- A imagem principal do topo não usa
loading="lazy". - O CLS medido no Lighthouse fica em 0,1 ou menos com rede lenta.
Abra a sua página de produto com a rede limitada e as regiões de deslocamento destacadas: quantas vezes a tela pisca em azul antes de parar quieta?
Referência: https://web.dev/articles/optimize-cls