< BACK Core Web Vitals em Sites Grandes: Como Atingir LCP Menor que 1.5s -- ilustração em arte linear

Core Web Vitals em Sites Grandes: Como Atingir LCP Abaixo de 1.5s

Lá em 2022, um site de comparação de hosting caiu na minha caixa. Catálogo grande, cerca de 4.000 páginas, estrutura de categorias profundamente aninhada, links de afiliado espalhados por todo lugar, imagens hero do tamanho de pequenos continentes. O Google Search Console deles era um horror. LCP em 4,2 segundos no mobile. INP (naquele tempo ainda chamado de FID) borderline. O cliente já tinha gasto £6.000 com uma agência anterior que tinha jogado um CDN em cima e chamado de pronto.

Esse projeto é o que eventualmente moldou como a gente pensa sobre performance na Seahawk para sites com alto número de páginas, directory sites, plataformas de listagem, propriedades de hosting review como builds estilo HostList. O que vem a seguir é o playbook real.performance at Seahawk for high-page-count sites, directory sites, listing platforms, hosting review properties like HostList-style builds. What follows is the actual playbook.

---

Por Que Sites Grandes Quebram LCP de Forma Diferente

Sites pequenos têm problemas simples. Uma imagem hero, um tema, um plugin fazendo muito. Conserte essas três coisas e você está abaixo de 2 segundos.

Sites grandes? Animal completamente diferente. O elemento LCP muda dependendo de qual página você está. Um arquivo de categoria tem um candidato LCP diferente do que uma página de detalhe do produto, que tem um candidato diferente da homepage. A maioria das ferramentas de performance reporta um único score. Esse número é uma mentira, é uma média de um conjunto vastamente variado de páginas, e consertar a homepage enquanto ignora as 3.800 páginas de listagem abaixo dela é exatamente como agências ganham más reputações.which page you're on. A category archive has a different LCP candidate than a product detail page, which has a different candidate than the homepage. Most performance tools report a single score. That number is a lie, it's an average of a wildly varied set of pages, and fixing the homepage while ignoring the 3,800 listing pages underneath it is exactly how agencies earn bad reputations.

A documentação de Core Web Vitals do Google é clara que field data, o que usuários reais experimentam, medido no Chrome User Experience Report, é o que o Google realmente usa para sinais de ranking. Lab data do PageSpeed Insights é direcional, não definitivo. Eu já vi sites pontuar 95 no PSI e ainda assim ter Poor LCP em dados de CrSX. Não confunda os dois.Core Web Vitals documentation from Google is clear that field data, what real users experience, measured in Chrome User Experience Report, is what Google actually uses for ranking signals. Lab data from PageSpeed Insights is directional, not definitive. I've seen sites score 95 on PSI and still have Poor LCP in CrSX data. Don't confuse the two.

Os Três Culpados Reais em Sites de Listagem

Em todos os grandes sites que auditei (e já passei por centenas neste ponto), falhas de LCP rastreiam três causas raiz quase sempre:

  • Imagens hero ou card não otimizadas, frequentemente servidas em resolução cheia, formato errado, nenhuma dica de fetchpriority, often served at full resolution, wrong format, no fetchpriority hint
  • Scripts third-party que bloqueiam renderização, rastreadores de afiliado, redes de anúncio, widgets de comparação carregando antes do navegador conseguir pintar qualquer coisa, affiliate trackers, ad networks, comparison widgets loading before the browser can paint anything
  • TTFB inflacionando o orçamento de LCP, resposta lenta do servidor devorando 600-900ms antes da página nem começar a carregar, slow server response eating 600-900ms before the page even starts loading

Esse terceiro aí é o que as pessoas subestimam. Se seu TTFB é 700ms, você já gastou quase metade do seu orçamento de LCP "Good" antes do navegador ter renderizado um único pixel. Escolha de hosting e caching server-side não são preocupações de DevOps, são preocupações de SEO.

---

Comece com TTFB: É Primeiro um Problema de Hosting e Caching

O projeto do tipo HostList que mencionei acima? Primeira coisa que fiz foi rodar WebPageTest de cinco localizações geográficas diferentes. TTFB era consistentemente 680-820ms. O site estava em um host compartilhado na Virgínia. A maioria do tráfego orgânico deles vinha do Reino Unido e Alemanha.WebPageTest from five different geographic locations. TTFB was consistently 680-820ms. The site was on a shared host in Virginia. Most of their organic traffic came from the UK and Germany.

Mudei para um host WordPress gerenciado com edge nodes em Londres e Frankfurt. Configurei cache de página inteira com tempos de vida de 12 horas nas páginas de listagem (os dados não mudavam com tanta frequência mesmo assim). TTFB caiu para 120-180ms em requisições repetidas, 280-350ms em primeiros acessos com cache miss. Essa mudança única reduziu aproximadamente 500ms do LCP antes de eu tocar em uma única imagem.WordPress host with edge nodes in London and Frankfurt. Configured full-page caching with cache lifetimes of 12 hours on listing pages (the data didn't change that often anyway). TTFB dropped to 120-180ms on repeat requests, 280-350ms on first-hit cache misses. That single change shaved roughly 500ms off LCP before I touched a single image.

Algumas coisas que sempre verifico no lado do hosting:

  1. O cache de página completa está realmente funcionando? Verifique o header de resposta X-Cache. Se disser MISS em cada requisição, sua camada de cache não está funcionando. Check the X-Cache response header. If it says MISS on every single request, your caching layer isn't functioning.
  2. O servidor de origem está geograficamente perto da sua audiência principal? Parece óbvio. Você ficaria surpreso com a frequência que está errado. This sounds obvious. You'd be surprised how often it's wrong.
  3. Keep-alive está habilitado? Alguns hosts mais baratos ainda desabilitam conexões persistentes. Estranho em 2024, mas acontece. Some cheaper hosts still disable persistent connections. Wild in 2024, but it happens.
  4. HTTP/2 ou HTTP/3 estão ativos? Execute curl -I --http2 https://yourdomain.com e verifique o protocolo na resposta. Run curl -I --http2 https://yourdomain.com and check the protocol in the response.

Não toque em otimização de imagens até ter resolvido TTFB. Otimizar imagens em um servidor lento é como pintar uma casa que está pegando fogo.

---

The LCP Image Problem (And Why `fetchpriority` Changes Everything)

Certo. Imagens. Em um site de listagem com layouts de grade de cards, o elemento LCP é quase sempre a imagem do primeiro card acima da dobra, ou o banner hero. O navegador tem que descobri-la, busca-la, decodifica-la, e renderiza-la. Cada um desses passos pode ser atrasado.

Aqui está o que realmente fizemos no projeto HostList, em ordem:

  1. Converti todas as imagens dos cards para WebP, usando a conversão em lote do Imagify. O tamanho médio dos arquivos caiu 58% sem perda de qualidade visível nos tamanhos de miniatura dos cards que estávamos usando (280×180px de exibição, servidos em 2x para retina)., using Imagify's bulk conversion. Average file size dropped 58% without visible quality loss at the card thumbnail sizes we were using (280×180px display, served at 2x for retina).
  2. Adicionei `fetchpriority="high"` à primeira imagem do card. Essa única mudança tirou ~200ms do LCP medido no WebPageTest. O navegador para de tratar como uma imagem lazy regular e a coloca na fila do preload scanner imediatamente., This one change alone knocked ~200ms off measured LCP in WebPageTest. The browser stops treating it like a regular lazy image and queues it immediately in the preload scanner.
  3. Removi `loading="lazy"` das duas primeiras linhas de imagens dos cards. Lazy loading é brilhante para imagens abaixo da dobra. Na primeira linha visível, prejudica ativamente. Ela diz ao navegador para não buscar a imagem até estar perto do viewport, que já está., Lazy loading is brilliant for below-fold images. On the first visible row, it actively hurts you. It tells the browser to not fetch the image until it's near the viewport, which it already is.
  4. Adicionamos uma tag `<link rel="preload">` para a imagem hero no `<head>` especificamente no template da homepage. in the <head> on the homepage template specifically.

Essa sequência levou o LCP da homepage de 3.1s para 1.4s em condições de lab. Os dados de campo seguiram em aproximadamente 28 dias (é mais ou menos quanto tempo leva para os dados do CrUX refletirem mudanças em escala).

Uma Nota sobre Imagens Responsivas

Se você está servindo a mesma imagem de 1400px de largura para um dispositivo móvel, está queimando largura de banda e adicionando tempo de decodificação. Use srcset corretamente. Eu sei que isso parece uma conversa de 2016, mas ainda vejo em provavelmente 40% dos sites que passam pela Seahawk. A função WordPress wp_get_attachment_image() gera srcset automaticamente, mas apenas se a imagem foi enviada com resolução suficiente e o tema não a suprimiu com add_filter('max_srcset_width', ...).srcset properly. I know this sounds like a 2016 conversation but I still see it on probably 40% of the sites that come through Seahawk. The WordPress wp_get_attachment_image() function generates srcset automatically, but only if the image was uploaded at sufficient resolution and the theme hasn't suppressed it with add_filter('max_srcset_width', ...).

---

Scripts que Bloqueiam a Renderização: O Imposto do Site de Afiliados

Sites de comparação de hospedagem e plataformas de listagem vivem de receita de afiliado. Isso significa scripts de rastreamento de terceiros. Commission Junction, Impact, Awin, rastreadores de pixel customizados, eles se acumulam. Já contei 14 origens de script de terceiros separadas em um único site de listagem. Cada uma é uma consulta DNS separada, conexão TCP e handshake TLS antes de um único byte daquele script ser recebido.

A solução não é remover os scripts. Você não pode, a receita depende deles. A solução é sequenciamento.

Nenhum script de terceiros deve bloquear a renderização inicial do elemento LCP. Ponto final.

Na prática, isso significa:

  • Mova todos os scripts de afiliados/análise para carregar após o evento DOMContentLoaded, não na <head>.after the DOMContentLoaded event, not in <head>.
  • Use atributos async ou defer em todos os scripts que você controla.async or defer attributes on every script you control.
  • Para scripts que você não controla (injetados por gerenciadores de tags), carregue o Google Tag Manager em si com defer. Sim, isso é seguro para a maioria dos casos de uso de rastreamento de afiliado, e a documentação própria do GTM reconhece essa abordagem.defer, yes, this is safe for most affiliate tracking use cases, and GTM's own documentation acknowledges this approach.
  • Use um gerenciador de scripts como Asset CleanUp Pro ou o recurso de atraso de script do WP Rocket para adiar terceiros não essenciais até a interação do usuário (primeiro scroll ou primeiro clique).

Na reconstrução do HostList, adiar scripts de terceiros reduziu o Total Blocking Time de 1.840ms para 290ms. TBT não é uma Core Web Vital diretamente, mas se correlaciona fortemente com INP, que é.is.

---

Carregamento de Fontes: O Assassino Silencioso do LCP que Ninguém Comenta

Fontes customizadas causam um modo de falha específico. O navegador renderiza seu layout, atinge o elemento de texto do LCP (às vezes o LCP é um heading, não uma imagem), e então aguarda o arquivo de fonte antes de pintar. Isso é chamado Flash of Invisible Text, e atrasa o LCP em qualquer lugar de 200ms a mais de um segundo, dependendo do tamanho do arquivo de fonte e proximidade do servidor.

Duas coisas resolvem isto:

  • `font-display: swap` na sua declaração @font-face. O navegador renderiza em uma fonte substituta imediatamente e troca quando a fonte customizada carrega. O candidato a LCP é pintado no tempo. in your @font-face declaration, the browser renders in a fallback font immediately and swaps when the custom font loads. LCP candidate gets painted on time.
  • Auto-hospede suas fontes. Google Fonts adiciona uma requisição cross-origin. Auto-hospedar com a ferramenta google-webfonts-helper permite servir fontes do seu próprio domínio, cortando essa conexão extra.google-webfonts-helper tool lets you serve fonts from your own domain, cutting that extra connection.

Converti um grande diretório de sites da Google Fonts em cerca de 45 minutos usando essa ferramenta. O LCP melhorou por 180ms. Não é transformador sozinho, mas combinado com tudo mais, essas margens se acumulam.

---

Medindo o Que Realmente Importa no Campo

Dados do CrUX são a verdade absoluta. Mas só atualiza mensalmente e apenas para URLs com tráfego suficiente. Para sites grandes com milhares de páginas, você precisa de algo mais granular.

Uso a API do PageSpeed Insights em script em uma amostra representativa de URLs, normalmente as 100 páginas principais por tráfego, 50 páginas de nível de categoria e 20 páginas de deep-catalogue "thin". Executar isso mensalmente dá uma distribuição de desempenho adequada, não um score de ponto único.PageSpeed Insights API scripted across a representative sample of URLs, typically the top 100 pages by traffic, 50 category-level pages, and 20 "thin" deep-catalogue pages. Running this monthly gives a proper performance distribution, not a single-point score.

No Lighthouse CI (que rodamos em pipelines de CI/CD para clientes que têm ciclos de desenvolvimento), validamos contra:

  • LCP ≤ 2,5s em lab (target conservador, já que o field tende a ficar 10-15% atrás do lab)
  • TBT ≤ 300ms
  • CLS ≤ 0.1

Mas honestamente, para um build tipo HostList onde o objetivo é LCP sub-1.5s, os targets de lab precisam ser mais apertados. Definimos LCP ≤ 1.8s em Lighthouse CI para esses projetos, o que normalmente produz 1.3-1.5s em dados de campo uma vez que o CrUX se atualiza.

---

Juntando Tudo: O Resultado de HostList

Depois de passar por tudo acima, migração de hospedagem, cache de página completa, conversão de formato de imagem, fetchpriority em candidatos de LCP, remoção de lazy-load de linhas acima da dobra, deferência de scripts e auto-hospedagem de fontes, aqui estão os números que obtivemos:fetchpriority on LCP candidates, lazy-load removal from above-fold rows, script deferral, and font self-hosting, here's what the numbers looked like:

  • TTFB: 780ms → 160ms (mediana, visitantes do UK): 780ms → 160ms (median, UK visitors)
  • LCP (lab, mobile): 4.2s → 1.4s: 4.2s → 1.4s
  • LCP (field, CrUX, 75º percentil): 3.8s → 1.6s (medido 60 dias após migração): 3.8s → 1.6s (measured 60 days post-migration)
  • TBT: 1.840ms → 290ms: 1,840ms → 290ms
  • CLS: já estava bom em 0.03, sem alterações: was already fine at 0.03, unchanged

Nem todo site vai ganhar uma melhoria de 2.8 segundos. Mas praticamente todo grande site de listagem com o qual trabalhei teve todos esses problemas simultaneamente, o que significa que os ganhos se acumulam. Corrija uma coisa e você ganha 300ms. Corrija todas e você ganha 2.5 segundos.

---

FAQ

A hospedagem realmente importa tanto para LCP?

Sim, provavelmente mais do que qualquer outra coisa no início. Se seu TTFB está acima de 500ms, nenhuma quantidade de otimização de imagem vai te levar a um LCP "Good". TTFB é a fundação em que tudo mais se baseia. Coloque-o abaixo de 200ms primeiro, depois se preocupe com o resto.

Devo usar um CDN em vez de migrar de hospedagem?

Um CDN ajuda com a entrega de assets estáticos e pode reduzir TTFB para HTML full-page em cache, se configurado corretamente. Mas muitas configurações de CDN só fazem cache de assets, não de respostas HTML completas. Verifique se o seu CDN está realmente servindo HTML em cache ou só offloadando imagens. Se for o último caso, um host origin melhor fará mais pela LCP.

`fetchpriority="high"` tem suporte amplo agora?

A partir de 2024, sim, é suportado em Chrome, Edge e Safari (desde Safari 17.2). O suporte do Firefox chegou no Firefox 132. Para navegadores que não suportam, é ignorado com segurança. Não há desvantagem em adicioná-lo ao seu elemento de imagem LCP.

Quanto tempo leva para os dados do CrUX refletirem melhorias?

Aproximadamente 28 dias a partir de quando usuários reais começam a experimentar a versão mais rápida do site. CrUX usa uma janela de 28 dias contínua. Então se você fizer deploy de mudanças hoje, sua pontuação de field data não vai refletir totalmente por cerca de um mês. Não entre em pânico se PageSpeed Insights ainda mostrar "Needs Improvement" no dia depois do seu sprint de otimização.

Qual é a mudança de maior impacto para um site de listagem?

Em quase todos os projetos, foi TTFB. Mas o segundo maior tem sido consistentemente remover loading="lazy" das imagens de card above-fold e adicionar fetchpriority="high". Juntas essas duas coisas normalmente respondem por 40-60% da melhoria total de LCP. Tudo o mais são ganhos compostos em cima dessa fundação.loading="lazy" from above-fold card images and adding fetchpriority="high". Together those two things usually account for 40-60% of the total LCP improvement. Everything else is compounding gains on top of that foundation.

---

Trabalho de performance em sites grandes é principalmente encanamento. Sem glamour, metódico, e profundamente satisfatório quando você reduz um LCP de 4 segundos para 1.4 segundos e vê o tráfego orgânico aumentar dois meses depois. Não existe uma única configuração mágica, apenas uma sequência de decisões específicas tomadas na ordem correta.

Deixe o servidor rápido. Depois faça o elemento LCP ser descoberto e buscado cedo. Depois tire tudo mais do caminho dele.

< BACK