LCP (Largest Contentful Paint): Como Dominar a Métrica que Mais Sites Falham

Mais de 40% dos websites falham o LCP. Decompomos a métrica nas 4 sub-partes com estratégias concretas de otimização, código prático para Next.js, Nuxt e Astro, e um checklist de 10 passos para dominar o Largest Contentful Paint.

Introdução — O LCP é a Métrica Mais Difícil de Passar

Vou ser direto: se há uma métrica dos Core Web Vitals que provavelmente está a prejudicar o seu site, é o LCP. Quando olhamos para os dados do Chrome User Experience Report (CrUX) de dezembro de 2025, o cenário não é bonito — apenas 67,6% das origens têm um LCP considerado "bom". E se considerarmos os três Core Web Vitals em simultâneo, só 54,4% passam. Ou seja, mais de 40% dos websites não atingem sequer o limiar aceitável de LCP. Se o seu site está nesse grupo, está literalmente a perder posições no Google.

Mas afinal, o que é o LCP? O Largest Contentful Paint mede o tempo que o maior elemento visível de conteúdo demora a ser renderizado no ecrã — pode ser uma imagem hero, um bloco de vídeo ou até um parágrafo de texto dominante. Não mede quando "algo" aparece (isso é o FCP), mas sim quando o conteúdo principal é apresentado ao utilizador. É, na prática, a métrica que melhor captura aquela sensação de "ok, esta página já carregou".

Os limiares são simples:

  • Bom: ≤ 2,5 segundos
  • Precisa de Melhorias: 2,5 – 4 segundos
  • Fraco: > 4 segundos

O Google usa o LCP diretamente como sinal de ranking. Quando duas páginas competem pela mesma palavra-chave com qualidade de conteúdo semelhante, a que tiver melhores Core Web Vitals ganha. Ponto. E com a crescente relevância das AI Overviews, sites com desempenho fraco ficam cada vez menos visíveis nos resultados de pesquisa.

No nosso artigo anterior sobre INP, cobrimos a responsividade — o outro pilar crítico dos Core Web Vitals. Este guia foca-se inteiramente na velocidade de carregamento, e mais especificamente, em como dominar a métrica que mais websites falham.

Anatomia do LCP — As 4 Sub-Partes que Precisa de Compreender

Um dos erros mais comuns (e já vi isto em equipas bastante experientes) é tratar o LCP como um valor monolítico — "o meu LCP é 3,8 segundos, preciso de o reduzir". Isto é como dizer "o meu carro está lento" sem saber se o problema é o motor, os pneus ou o combustível.

Na realidade, o LCP é a soma de 4 sub-partes sequenciais, e cada uma exige correções completamente diferentes. Vamos a cada uma delas.

1. TTFB (Time to First Byte)

A primeira sub-parte é o tempo desde o início da navegação até o browser receber o primeiro byte da resposta do servidor. Inclui resolução DNS, ligação TCP, negociação TLS e processamento no servidor.

E aqui está o problema: para origens com LCP fraco, a mediana do p75 do TTFB é de 2.270ms. Leu bem — o servidor sozinho já consome quase a totalidade do orçamento de 2,5 segundos. Se o seu TTFB é elevado, nenhuma otimização de imagens ou de front-end vai salvar o seu LCP. Nenhuma.

Correções principais: implementar um CDN, cache do lado do servidor (Redis, Varnish), otimizar o código back-end, considerar edge computing (Cloudflare Workers, Vercel Edge Functions).

2. Resource Load Delay (Atraso no Carregamento do Recurso)

Esta é a fase entre o browser receber o HTML e o momento em que começa efetivamente a descarregar o recurso LCP (tipicamente a imagem hero). E esta é, honestamente, a sub-parte mais subestimada de todas — os dados provam-no de forma esmagadora.

Em websites com LCP fraco, o tempo gasto a esperar para começar a descarregar o recurso é quase 4 vezes superior ao tempo efetivo de download. São 1,3 segundos desperdiçados entre o TTFB e o pedido da imagem. Mais de metade do orçamento de 2,5 segundos, evaporados antes sequer de a imagem começar a ser transferida.

Porque é que isto acontece? Porque o recurso LCP não é descobrível pelo preload scanner do browser. As causas mais comuns:

  • Imagens definidas via CSS (background-image) — completamente invisíveis para o scanner
  • Imagens carregadas via JavaScript (client-side rendering) — o browser simplesmente não sabe que existem até o JS executar
  • Cadeias de redirecionamentos ou dependências de CSS/JS antes de descobrir o recurso

A solução? Garantir que o URL do recurso LCP é visível diretamente no HTML, para que o preload scanner o encontre o mais cedo possível.

3. Resource Load Duration (Duração do Carregamento)

Esta é a fase que a maioria das equipas tenta otimizar primeiro — o tempo efetivo de download do recurso LCP. E aqui vem a surpresa que apanha muita gente desprevenida.

Os dados mostram que esta é a sub-parte mais curta do LCP para a maioria das origens. Menos de 10% do tempo total de p75 LCP é gasto no download da imagem.

Isto não significa que seja irrelevante — cada milissegundo conta. Mas se a sua estratégia de otimização se limita a comprimir imagens, está a atacar a fatia mais pequena do problema. É um pouco como reorganizar as cadeiras no Titanic (ok, talvez não tão dramático, mas percebe a ideia).

Correções: utilizar formatos modernos (AVIF, WebP), imagens responsivas com srcset/sizes, servir via CDN, aplicar compressão adequada.

4. Element Render Delay (Atraso na Renderização)

A última fase é o tempo desde o recurso estar completamente descarregado até ser efetivamente pintado no ecrã. Este é um problema do thread principal, não um problema de rede.

As causas incluem CSS que bloqueia a renderização, tarefas longas de JavaScript que ocupam o main thread, e grandes recálculos de layout do DOM. O objetivo é que esta fase represente no máximo 10% do orçamento total de LCP.

Correções: diferir JavaScript não crítico, dividir tarefas longas, minimizar CSS que bloqueia a renderização, reduzir a complexidade do DOM.

Regra de ouro: Antes de otimizar o LCP, decomponha-o nas 4 sub-partes. A sub-parte mais longa é onde deve investir o seu esforço primeiro. Na maioria dos casos, é o Resource Load Delay — não o download da imagem. Já perdi a conta de quantas vezes vi equipas a otimizar compressão de imagens quando o verdadeiro problema era a descoberta tardia do recurso.

As Estratégias de Otimização Mais Eficazes (Com Código)

3.1 Tornar o Recurso LCP Detetável pelo Preload Scanner

O preload scanner é um parser secundário do browser que analisa o HTML em bruto para descobrir recursos a descarregar antes de o parser principal chegar a eles. Se o recurso LCP não está visível neste HTML, perde-se tempo precioso. E muito.

Mau — Imagem via CSS (invisível ao scanner):

.hero {
  background-image: url('/hero.webp');
  width: 100%;
  height: 600px;
}

Bom — Tag img diretamente no HTML:

<img
  src="/hero.webp"
  alt="Imagem principal do artigo"
  fetchpriority="high"
  width="1200"
  height="600"
>

Mau — Imagem carregada via JavaScript (client-side rendering):

// O browser não sabe que esta imagem existe até o React hidratar
useEffect(() => {
  setImage(data.heroUrl);
}, []);

Bom — Renderização do lado do servidor ou preload explícito. Se utiliza um framework com SSR (Next.js, Nuxt, Astro), o recurso LCP deve estar no HTML servido pelo servidor. Se por alguma razão isso não é possível, use um <link rel="preload"> no <head>.

3.2 fetchpriority e Preload — O Duo que Faz a Diferença

O atributo fetchpriority="high" é, na minha opinião, a otimização com melhor relação esforço/impacto que existe para o LCP. Sério. Uma única linha de código que indica ao browser que este recurso deve ter prioridade máxima no carregamento.

E os resultados falam por si:

  • Google Flights: melhoria de 700ms no LCP apenas ao adicionar fetchpriority="high"
  • Etsy: melhoria de 4% no LCP; alguns websites reportaram melhorias de 20-30% em testes laboratoriais
<!-- Aplicar fetchpriority na imagem LCP -->
<img
  src="/hero.avif"
  alt="Imagem principal"
  fetchpriority="high"
  width="1200"
  height="600"
>

<!-- Preload com fetchpriority para recursos descobertos tardiamente -->
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high">

Para sites que controlam o servidor HTTP, os Early Hints (103) permitem ao browser começar a descarregar recursos antes mesmo de a resposta HTML estar pronta:

HTTP/1.1 103 Early Hints
Link: </hero.avif>; rel=preload; as=image; fetchpriority=high

Com Early Hints, o browser recebe indicações sobre recursos críticos enquanto o servidor ainda está a processar o HTML. Na prática, isto pode eliminar centenas de milissegundos do Resource Load Delay — e nalguns casos que já acompanhei, a diferença foi brutal.

3.3 Imagens Modernas: AVIF, WebP e o Elemento Picture

A escolha do formato de imagem tem impacto direto no Resource Load Duration. Em 2026, a hierarquia é bastante clara:

  • AVIF: até 60% mais pequeno que JPEG, com suporte em mais de 85% dos browsers
  • WebP: 25-34% mais pequeno que JPEG, com suporte superior a 95%
  • JPEG: o fallback universal, mas significativamente maior

O elemento <picture> permite oferecer formatos progressivamente, garantindo que cada browser recebe o melhor formato que suporta:

<picture>
  <source srcset="/hero.avif" type="image/avif">
  <source srcset="/hero.webp" type="image/webp">
  <img
    src="/hero.jpg"
    alt="Imagem principal do artigo"
    fetchpriority="high"
    width="1200"
    height="600"
  >
</picture>

Para imagens responsivas que se adaptam ao tamanho do ecrã, combine srcset com sizes:

<img
  srcset="/hero-400.avif 400w, /hero-800.avif 800w, /hero-1200.avif 1200w"
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 80vw, 1200px"
  src="/hero-1200.avif"
  alt="Imagem principal do artigo"
  fetchpriority="high"
  width="1200"
  height="600"
>

Isto garante que um utilizador de telemóvel não descarrega uma imagem de 1200px quando 400px seriam suficientes — uma poupança que pode ultrapassar 80% do peso do ficheiro. Parece óbvio, mas ficaria surpreendido com a quantidade de sites que ainda servem imagens de desktop a todos os dispositivos.

3.4 Lazy Loading — Usar com Muito Cuidado

Aqui está uma das armadilhas mais comuns que vejo por aí: aplicar loading="lazy" indiscriminadamente a todas as imagens, incluindo a imagem LCP. Os dados não mentem — websites que aplicam lazy loading ao elemento LCP têm um LCP 35% mais lento.

O motivo é simples. O loading="lazy" atrasa o download da imagem até ela entrar no viewport. Mas a imagem LCP já está no viewport desde o início! Ao adicionar lazy loading, está a forçar o browser a esperar pela renderização do layout antes de iniciar o download — adicionando centenas de milissegundos desnecessários.

O padrão correto:

<!-- Imagem LCP — carregamento prioritário -->
<img src="/hero.avif" fetchpriority="high" alt="Imagem principal">

<!-- Imagens abaixo da dobra — lazy loading -->
<img src="/produto-1.avif" loading="lazy" alt="Produto 1">
<img src="/produto-2.avif" loading="lazy" alt="Produto 2">
<img src="/produto-3.avif" loading="lazy" alt="Produto 3">

Regra: nunca aplique loading="lazy" à imagem hero nem a qualquer elemento acima da dobra. Reserve o lazy loading exclusivamente para conteúdo que o utilizador tem de fazer scroll para ver. Sem exceções.

3.5 Reduzir o TTFB

Se o TTFB consome uma fatia significativa do seu orçamento LCP, nenhuma otimização de front-end vai compensar. É como tentar pintar uma casa cujos alicerces estão a ceder — bonito, mas inútil. Estas são as alavancas principais:

Headers de Cache-Control adequados:

# Recursos estáticos imutáveis (imagens, fontes, CSS/JS com hash)
Cache-Control: public, max-age=31536000, immutable

# Páginas HTML dinâmicas com revalidação
Cache-Control: public, max-age=0, s-maxage=3600, stale-while-revalidate=86400

A diretiva stale-while-revalidate é particularmente poderosa: serve o conteúdo em cache imediatamente ao utilizador enquanto revalida em segundo plano. O utilizador vê a página instantaneamente; a atualização acontece de forma transparente. É, sinceramente, uma das diretivas mais subapreciadas do HTTP.

Compressão Brotli no Nginx (superior ao Gzip em 15-20%):

brotli on;
brotli_comp_level 6;
brotli_types text/html text/css application/javascript image/svg+xml;

Edge computing permite processar pedidos no ponto de presença mais próximo do utilizador, eliminando a latência de ida e volta a um servidor de origem distante. Soluções como Cloudflare Workers ou Vercel Edge Functions podem reduzir o TTFB para menos de 100ms na maioria dos mercados.

3.6 Eliminar CSS e JavaScript que Bloqueiam a Renderização

CSS e JavaScript no <head> bloqueiam a renderização por defeito. O browser não pinta nada no ecrã até ter descarregado, analisado e executado estes recursos. Para o LCP, isto traduz-se diretamente em Element Render Delay.

Inline do CSS crítico e carregamento assíncrono do restante:

<head>
  <!-- CSS crítico inline — renderizado imediatamente -->
  <style>
    .hero { width: 100%; height: auto; }
    .header { display: flex; align-items: center; }
  </style>

  <!-- CSS restante carregado de forma assíncrona -->
  <link rel="preload" href="/styles.css" as="style"
        onload="this.onload=null;this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="/styles.css"></noscript>
</head>

Scripts com defer e async:

<!-- defer: descarrega em paralelo, executa após o parsing do HTML -->
<script src="/analytics.js" defer></script>

<!-- async: descarrega em paralelo, executa assim que disponível -->
<script src="/chat-widget.js" async></script>

A diferença chave: defer garante a ordem de execução e espera pelo fim do parsing; async executa assim que o download termina, sem garantias de ordem. Para analytics e widgets não críticos, async é geralmente a escolha certa. Para scripts da aplicação que dependem uns dos outros, use defer.

3.7 Otimizar Fontes Web

Fontes web são uma causa frequente de atrasos invisíveis no LCP — especialmente quando o elemento LCP é um bloco de texto. Se o browser espera pelo download da fonte antes de renderizar o texto, o LCP sofre diretamente. E o pior? Muitas vezes nem nos apercebemos porque o texto simplesmente "não aparece" durante uns segundos (o famoso FOIT — Flash of Invisible Text).

Preload da fonte crítica:

<link rel="preload" href="/fonts/inter.woff2" as="font"
      type="font/woff2" crossorigin>

font-display: swap e fallback otimizado:

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-display: swap;
}

/* Fonte de fallback com métricas ajustadas para minimizar layout shift */
@font-face {
  font-family: 'Inter-fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

Com font-display: swap, o browser renderiza o texto imediatamente com a fonte de fallback e troca quando a fonte personalizada fica disponível. As propriedades size-adjust, ascent-override e descent-override alinham as métricas da fonte de fallback com a fonte definitiva, minimizando o salto visual (CLS) durante a troca. É um detalhe pequeno que faz uma diferença enorme na experiência do utilizador.

Otimização por Framework

Cada framework moderno oferece ferramentas específicas para otimizar o LCP. Conhecer as particularidades de cada um poupa-lhe tempo — e evita que cometa erros que já foram cometidos por milhares de developers antes de si.

4.1 Next.js (React)

O componente next/image é a forma recomendada de servir imagens em Next.js. Gera automaticamente formatos modernos, tamanhos responsivos e adiciona o atributo fetchpriority quando indicado:

import Image from 'next/image';

export default function Hero() {
  return (
    <Image
      src="/hero.avif"
      alt="Imagem principal"
      width={1200}
      height={600}
      preload={true}
      fetchPriority="high"
      sizes="(max-width: 768px) 100vw, 1200px"
    />
  );
}

Ponto essencial: utilize SSR ou SSG para que a imagem LCP esteja presente no HTML inicial. Evite carregar a imagem hero dentro de um componente que dependa de useEffect ou de dados fetched no lado do cliente. Já vi este erro tantas vezes em projetos Next.js que quase merecia um aviso no próprio framework.

4.2 Nuxt (Vue)

O componente NuxtImg do módulo @nuxt/image oferece otimização automática com suporte a múltiplos formatos e tamanhos:

<template>
  <NuxtImg
    src="/hero.avif"
    alt="Imagem principal"
    width="1200"
    height="600"
    preload
    loading="eager"
    format="avif,webp"
    sizes="100vw md:80vw lg:1200px"
  />
</template>

A propriedade preload garante que é injetado um <link rel="preload"> no <head>. Combine com loading="eager" para garantir que não é aplicado lazy loading ao elemento LCP.

4.3 Astro

O Astro destaca-se pela sua abordagem zero-JavaScript por defeito e otimização de imagens integrada. É, aliás, uma das razões pelas quais tem vindo a ganhar tanta tração para sites focados em conteúdo:

---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.avif';
---
<Image
  src={heroImage}
  alt="Imagem principal"
  widths={[400, 800, 1200]}
  sizes="(max-width: 600px) 100vw, 1200px"
  loading="eager"
  fetchpriority="high"
/>

O Astro processa as imagens no momento do build, gerando automaticamente múltiplos tamanhos e formatos. O resultado é HTML estático com imagens perfeitamente otimizadas — uma combinação ideal para LCP.

Diagnosticar e Monitorizar o LCP

Não se pode melhorar o que não se mede. E no caso do LCP, medir apenas o valor total não chega — é fundamental ver a decomposição nas 4 sub-partes para saber exatamente onde atuar.

5.1 Chrome DevTools — Painel de Performance

O painel Performance do Chrome DevTools é o ponto de partida para qualquer investigação de LCP. Eis o processo:

  1. Abra o DevTools (F12) e selecione o separador Performance
  2. Grave um trace de carregamento da página (clique em Record e recarregue)
  3. Procure o marcador LCP na timeline — indica o momento exato e o elemento
  4. O painel Performance Insights mostra a decomposição do LCP nas sub-partes, permitindo identificar imediatamente o gargalo

Dica: ative a opção "Web Vitals" no separador Performance para visualizar os marcadores de LCP, FCP e layout shifts diretamente na timeline. É daquelas funcionalidades escondidas que, depois de descobrir, não consegue viver sem.

5.2 Biblioteca web-vitals (RUM)

Para medir o LCP em utilizadores reais (dados de campo), a biblioteca web-vitals do Google com modo de atribuição é indispensável. Fornece não apenas o valor do LCP, mas a decomposição completa nas 4 sub-partes:

import { onLCP } from 'web-vitals/attribution';

onLCP((metric) => {
  const { value, attribution } = metric;
  const {
    element,
    url,
    timeToFirstByte,
    resourceLoadDelay,
    resourceLoadDuration,
    elementRenderDelay
  } = attribution;

  console.group(`LCP: ${value.toFixed(0)}ms`);
  console.log(`Elemento: ${element}`);
  console.log(`Recurso: ${url}`);
  console.log(`TTFB: ${timeToFirstByte.toFixed(0)}ms`);
  console.log(`Resource Load Delay: ${resourceLoadDelay.toFixed(0)}ms`);
  console.log(`Resource Load Duration: ${resourceLoadDuration.toFixed(0)}ms`);
  console.log(`Element Render Delay: ${elementRenderDelay.toFixed(0)}ms`);
  console.groupEnd();

  // Enviar para o sistema de analytics
  navigator.sendBeacon('/api/vitals', JSON.stringify({
    metric: 'LCP',
    value,
    ...attribution
  }));
});

Ao enviar estes dados para o seu sistema de analytics, pode construir dashboards que mostram a evolução de cada sub-parte ao longo do tempo — e verificar se as otimizações estão realmente a ter efeito. Porque, sejamos honestos, otimizar sem medir é só adivinhar.

5.3 PerformanceObserver API

Para monitorização mais direta sem dependências externas, a API nativa PerformanceObserver permite observar as entradas de LCP em tempo real:

const observer = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP Element:', lastEntry.element);
  console.log('LCP Time:', lastEntry.startTime);
  console.log('LCP Size:', lastEntry.size);
  console.log('LCP URL:', lastEntry.url);
});

observer.observe({ type: 'largest-contentful-paint', buffered: true });

Note que o browser pode emitir múltiplas entradas de LCP à medida que elementos maiores são renderizados. A última entrada é sempre a que conta como LCP final. O parâmetro buffered: true garante que recebe entradas que ocorreram antes de o observer ser registado — um detalhe fácil de esquecer, mas importante.

Casos de Estudo e Impacto Real

A teoria é útil, mas os números de implementações reais são o que realmente convence. Vejamos alguns exemplos concretos:

  • Google Flights: a simples adição de fetchpriority="high" à imagem hero resultou numa melhoria de 700ms no LCP. Uma linha de HTML, setecentos milissegundos. É difícil encontrar uma otimização com melhor retorno.
  • Etsy: a implementação de Priority Hints gerou uma melhoria de 4% no LCP em produção. Em testes laboratoriais controlados, a melhoria chegou aos 20-30%.
  • redBus: ao otimizar os Core Web Vitals de forma abrangente, registou um aumento de 7% nas vendas. Este é o tipo de impacto que justifica qualquer investimento em performance — e que faz os gestores de produto prestarem atenção.

Quando mais de 40% dos websites falham o limiar do LCP, otimizar esta métrica não é apenas uma questão técnica — é uma vantagem competitiva real. Se o seu concorrente tem um LCP de 4 segundos e o seu é de 1,8 segundos, o Google sabe distinguir. E os seus utilizadores também.

A performance web não é um custo — é um investimento com retorno mensurável em rankings, conversões e receita.

Checklist Final — Otimizar o LCP em 10 Passos

Para facilitar, aqui está a lista ordenada por prioridade — do maior ao menor impacto. Pode usar isto como referência rápida sempre que precisar de otimizar o LCP:

  1. Identificar o elemento LCP — Use o DevTools ou o Lighthouse para saber qual é o elemento (imagem, vídeo, bloco de texto) e o seu URL de recurso.
  2. Decompor o LCP nas 4 sub-partes — Utilize a biblioteca web-vitals com atribuição para identificar qual fase é o gargalo: TTFB, Resource Load Delay, Resource Load Duration ou Element Render Delay.
  3. Garantir que o recurso LCP é detetável pelo preload scanner — Eliminar imagens via CSS background-image e renderização do lado do cliente para o elemento LCP. Usar uma tag <img> diretamente no HTML.
  4. Adicionar fetchpriority="high" à imagem LCP — Uma única linha de código com impacto comprovado de centenas de milissegundos.
  5. Adicionar <link rel="preload"> no <head> — Para recursos que não estão diretamente no HTML (fontes, imagens de fundo essenciais), declarar explicitamente o preload.
  6. Utilizar formatos de imagem modernos — AVIF como primeira escolha, WebP como fallback, JPEG como último recurso. Usar o elemento <picture> para servir o melhor formato suportado.
  7. Implementar imagens responsivas com srcset/sizes — Servir o tamanho adequado ao dispositivo, evitando que telemóveis descarreguem imagens de desktop.
  8. Nunca aplicar lazy loading ao elemento LCP — O loading="lazy" é para imagens abaixo da dobra. A imagem hero deve ter sempre fetchpriority="high" e carregamento eager.
  9. Reduzir o TTFB — Implementar CDN, cache do lado do servidor, compressão Brotli, e considerar edge computing.
  10. Eliminar CSS e JavaScript que bloqueiam a renderização — Inline do CSS crítico, carregamento assíncrono do CSS restante, e uso de defer/async em scripts.

Perguntas Frequentes (FAQ)

Qual é a diferença entre LCP e FCP?

O First Contentful Paint (FCP) mede quando o primeiro conteúdo aparece no ecrã — pode ser um spinner de carregamento, um logótipo pequeno ou uma barra de navegação. O Largest Contentful Paint (LCP) mede quando o conteúdo principal é renderizado — tipicamente a imagem hero ou o bloco de texto dominante. É perfeitamente possível ter um FCP excelente (o spinner aparece em 500ms) mas um LCP terrível (a imagem hero só aparece aos 5 segundos). Resumindo: o FCP diz "algo apareceu"; o LCP diz "o conteúdo que interessa já está visível".

Porque é que o lazy loading piora o meu LCP?

O atributo loading="lazy" instrui o browser a adiar o download de uma imagem até ela estar próxima do viewport. Para a imagem LCP, que já está visível no viewport inicial, isto é contraproducente: o browser precisa primeiro de calcular o layout da página para determinar se a imagem está no viewport, e só depois inicia o download. Este passo extra pode adicionar centenas de milissegundos. A imagem LCP deve ser sempre carregada com prioridade máxima, não adiada.

O LCP do meu site é diferente no Lighthouse e no PageSpeed Insights. Porquê?

Boa pergunta, e é muito comum. O Lighthouse utiliza dados laboratoriais — simula condições controladas com um dispositivo e rede específicos. O PageSpeed Insights complementa com dados de campo do CrUX, que refletem a experiência de utilizadores reais com dispositivos e redes variados. Os dados de campo incluem telemóveis antigos com ligações 3G lentas, o que frequentemente resulta em valores piores. E aqui está o ponto crucial: os dados de campo são os que o Google utiliza para ranking, portanto são os mais relevantes para SEO.

Como é que o LCP afeta o meu ranking no Google?

Os Core Web Vitals (LCP, INP, CLS) são um sinal de ranking oficial do Google. Quando duas páginas competem pela mesma palavra-chave com qualidade de conteúdo semelhante, a que tiver melhores Core Web Vitals tende a posicionar-se acima. Com o crescimento das AI Overviews e das funcionalidades de pesquisa baseadas em IA, o Google favorece cada vez mais websites que oferecem uma boa experiência ao utilizador. Sites com desempenho fraco estão a ficar progressivamente menos visíveis nestes novos formatos de resultado.

É possível ter um LCP de 0ms?

Tecnicamente, sim — ou quase. Com a Speculation Rules API e o prerendering, o LCP percebido pode ser praticamente zero para navegações subsequentes. Isto acontece porque a página seguinte é totalmente renderizada em segundo plano antes de o utilizador clicar no link. Quando finalmente clica, a página aparece instantaneamente. Isto não se aplica à primeira visita (navegação fria), mas para a navegação dentro do site, o prerendering pode transformar completamente a perceção de velocidade. Se quiser aprofundar este tema, temos um artigo dedicado à Speculation Rules API aqui no blog.

Sobre o Autor Editorial Team

Our team of expert writers and editors.