O diagnóstico inicial
Recebemos um e-commerce de moda com tráfego relevante e uma taxa de conversão que estava caindo progressivamente. O cliente associava a queda ao produto e às campanhas. Antes de tocar em qualquer outra coisa, rodamos um diagnóstico de performance.
Resultados iniciais (PageSpeed Insights, mobile):
| Métrica | Valor inicial | Classificação |
|---|---|---|
| LCP | 4.2s | Ruim |
| CLS | 0.31 | Ruim |
| INP | 380ms | Precisa melhorar |
| FCP | 2.8s | Precisa melhorar |
LCP de 4.2 segundos significa que o conteúdo principal da página leva mais de 4 segundos para aparecer no celular. Cada segundo perdido é conversão perdida.
O que encontramos
Imagens não otimizadas
A homepage tinha 14 imagens de produto em formato JPEG, sendo servidas nos tamanhos originais (1200px × 1200px cada) sem redimensionamento responsivo. Em um celular com tela de 390px, o browser baixava imagens 3x maiores do que precisava.
JavaScript de terceiros bloqueando a renderização
O site tinha 6 scripts de terceiros carregando de forma síncrona no <head>: analytics, chat, pixels de remarketing, mapa de calor e dois scripts de A/B testing. Eles somavam 340kb de JavaScript que o browser precisava baixar e executar antes de renderizar qualquer coisa.
Fontes web sem font-display
Três famílias de fonte carregando sem font-display: swap. Resultado: texto invisível por até 2 segundos enquanto a fonte carregava. Isso é o que aparecia como CLS alto — o texto aparecia de repente e empurrava outros elementos.
LCP element: imagem de banner sem preload
O maior elemento da viewport era o banner principal — uma imagem de 800kb sem preload declarado. O browser só descobria que precisava dessa imagem depois de fazer o parse do HTML e do CSS.
As mudanças
1. Imagens em WebP com srcset responsivo
<picture>
<source
type="image/webp"
srcset="produto-390.webp 390w, produto-780.webp 780w, produto-1200.webp 1200w"
sizes="(max-width: 390px) 390px, (max-width: 780px) 780px, 1200px"
/>
<img src="produto-780.jpg" alt="Nome do produto" loading="lazy" />
</picture>Resultado: tamanho médio de imagem passou de 180kb para 42kb. Redução de 77%.
2. Scripts de terceiros diferidos
<!-- Antes -->
<script src="https://analytics.example.com/script.js"></script>
<!-- Depois -->
<script src="https://analytics.example.com/script.js" defer></script>Scripts de analytics e pixels foram movidos para defer ou carregados após o evento load. Scripts de A/B testing foram avaliados individualmente — um foi removido por ter impacto zero mensurável, o outro foi mantido mas carregado de forma assíncrona.
3. Preload do LCP element
<link
rel="preload"
as="image"
href="/banner-principal.webp"
fetchpriority="high"
/>Isso instrui o browser a baixar o banner principal com prioridade máxima, antes mesmo de processar o CSS que referencia a imagem.
4. Fontes com font-display: swap
@font-face {
font-family: 'Heading Font';
src: url('/fonts/heading.woff2') format('woff2');
font-display: swap;
}Com swap, o browser renderiza o texto com a fonte de fallback imediatamente e troca para a fonte web quando ela carregar. O CLS caiu de 0.31 para 0.04.
5. CDN para assets estáticos
Imagens e fontes foram movidas para uma CDN com edge nodes no Brasil. Latência de assets caiu de ~180ms para ~12ms para usuários em São Paulo.
Resultados depois das mudanças
| Métrica | Antes | Depois | Melhoria |
|---|---|---|---|
| LCP | 4.2s | 1.1s | −74% |
| CLS | 0.31 | 0.04 | −87% |
| INP | 380ms | 95ms | −75% |
| FCP | 2.8s | 0.9s | −68% |
Impacto em negócio (30 dias após a mudança):
- Taxa de conversão mobile: +23%
- Taxa de rejeição: −18%
- Tempo médio de sessão: +31%
O que não fizemos
Algumas otimizações comuns que não aplicamos nesse caso:
- Service Worker / PWA: teria adicionado complexidade sem ganho significativo para o perfil de uso desse e-commerce
- Lazy loading de componentes React: o problema era de assets, não de JavaScript de aplicação
- SSG para páginas de produto: a natureza dinâmica do estoque tornava isso impraticável sem ISR bem configurado
Conclusão
A maioria dos problemas de performance web tem solução bem conhecida. O desafio não é a técnica — é identificar o que está causando o maior impacto e priorizar as mudanças certas.
LCP alto quase sempre aponta para imagem ou fonte. CLS alto quase sempre é fonte ou conteúdo carregando assincronamente. INP alto é JavaScript pesado ou mal gerenciado.
Diagnostique antes de otimizar. A métrica que mais importa é aquela que mais impacta a experiência do usuário real.
Precisa de um diagnóstico de performance para o seu produto? Fale com nosso time.
