Skip to content
Go To Agency
/Desenvolvimento Web
Desenvolvimento Web

Core Web Vitals 2026 para o e-commerce português: INP, LCP e Cumulative Layout Shift na prática

Guia prático Core Web Vitals 2026 para o e-commerce português: corrigir INP, optimizar LCP com Next.js Image, prevenir CLS, edge caching Lisboa-node.

Por Robin Monteiro27 de maio de 202610 min · 2 168 mots
Core Web VitalsPerformanceNext.jsE-commercePortugal
Partilhar artigo
Core Web Vitals 2026 para o e-commerce português: INP, LCP e Cumulative Layout Shift na prática

Segundo os últimos dados da ACEPI (Associação da Economia Digital), 73% das compras online em Portugal são iniciadas no telemóvel e mais de metade são concluídas no mesmo dispositivo. Esta realidade mudou por completo o jogo da performance: o que outrora se media em segundos de carregamento, mede-se hoje em milissegundos de reatividade. O INP (Interaction to Next Paint), oficialmente substituto do FID desde Março de 2024, tornou-se o verdadeiro assassino silencioso dos Core Web Vitals em 2026 — e a maioria dos sites portugueses ainda não percebeu o impacto que isto tem nas conversões.

Quando analisamos o CrUX Report dos principais players nacionais — Worten, Continente Online, FNAC PT, Sport Zone, La Redoute PT — encontramos um padrão claro: o LCP foi razoavelmente domado, mas o INP em telemóveis de gama média (que representam o grosso do parque instalado em Portugal) continua a falhar o limiar dos 200 ms em mais de 40% das sessões. Este artigo é um guia técnico, sem rodeios, para resolver os três Core Web Vitals que importam em 2026, com snippets reais para Next.js 15 e RSC (React Server Components), e com referências concretas ao mercado português.

1. Medir e corrigir o INP no e-commerce português

O INP mede a latência da pior interação do utilizador durante toda a sessão — clique, toque ou tecla. O limiar verde é ≤ 200 ms, o laranja vai até 500 ms, e tudo o que ultrapasse isso é vermelho. Em e-commerce português, as interações mais problemáticas são tipicamente: adicionar ao carrinho, abrir o mega-menu de categorias, filtrar uma listagem (PLP) e abrir a galeria de imagens do produto (PDP).

Para medir o INP em produção, a abordagem correcta é instalar a biblioteca `web-vitals` directamente no `app/layout.tsx` e enviar os dados para um endpoint próprio (evitando o GA4, que amostra mal o INP em sessões longas):

// app/components/WebVitalsReporter.tsx
"use client";
import { useEffect } from "react";
import { onINP, onLCP, onCLS } from "web-vitals/attribution";

export function WebVitalsReporter() {
  useEffect(() => {
    const send = (metric: any) => {
      navigator.sendBeacon(
        "/api/vitals",
        JSON.stringify({
          name: metric.name,
          value: metric.value,
          rating: metric.rating,
          target: metric.attribution?.interactionTarget,
          url: window.location.pathname,
        })
      );
    };
    onINP(send, { reportAllChanges: false });
    onLCP(send);
    onCLS(send);
  }, []);
  return null;
}

A propriedade `interactionTarget` do objecto de atribuição é ouro puro: indica exactamente qual o elemento DOM responsável pela pior interação. Em três sites portugueses que auditámos no último trimestre, o vilão era sempre o mesmo — um handler `onClick` síncrono no botão "Adicionar ao carrinho" que despoletava atualização do estado global, chamada à API e re-render de toda a árvore de componentes em simultâneo.

A correção típica passa por três técnicas combinadas. Primeiro, usar `startTransition` do React para marcar actualizações não urgentes como concorrentes:

import { startTransition, useTransition } from "react";

function AddToCartButton({ productId }: { productId: string }) {
  const [isPending, startTransition] = useTransition();

  const handleClick = () => {
    // Feedback visual imediato (urgente)
    setOptimisticCount((c) => c + 1);

    // Pesado, mas não bloqueante
    startTransition(() => {
      addToCart(productId);
      revalidateCartBadge();
    });
  };

  return (
    <button onClick={handleClick} disabled={isPending}>
      Adicionar ao carrinho
    </button>
  );
}

Segundo, usar `useDeferredValue` para componentes pesados (mega-menu, filtros facetados). Terceiro, fragmentar tarefas longas com `scheduler.yield()` (já disponível em todos os Chromium-based desde Outubro 2025): em vez de um `for` que processa 500 produtos de uma vez, dividir em blocos de 50 e ceder controlo ao browser entre cada bloco. Esta técnica sozinha baixou o INP de 380 ms para 145 ms num cliente nosso do sector da moda.

2. Optimizar o LCP: Next.js Image, AVIF e priority hints

O LCP em e-commerce português é quase sempre a imagem principal do produto (PDP) ou o hero banner (homepage). O limiar verde mantém-se nos 2,5 s, mas o objetivo realista em 2026, com a infra-estrutura disponível, deve ser ≤ 1,8 s para se destacar da concorrência. Os players nacionais mais rápidos já navegam consistentemente abaixo dos 1,5 s na PDP graças a uma combinação de AVIF, CDN europeu e preload estratégico.

Com o Next.js 15 e o componente `<Image>` actualizado, a configuração correcta para uma imagem LCP é a seguinte:

// app/produto/[slug]/page.tsx
import Image from "next/image";

export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const product = await getProduct(slug);

  return (
    <Image
      src={product.heroImage}
      alt={product.name}
      width={800}
      height={800}
      priority
      fetchPriority="high"
      sizes="(max-width: 768px) 100vw, 50vw"
      quality={80}
      formats={["image/avif", "image/webp"]}
    />
  );
}

Pontos críticos: `priority` injecta automaticamente um `<link rel="preload">` no `<head>`; `fetchPriority="high"` força o browser a colocar este recurso no topo da fila de descodificação; `sizes` permite ao Next.js servir o tamanho exacto necessário para cada viewport, poupando até 70% de bytes em telemóveis. O AVIF tipicamente reduz o peso em 35-50% face ao WebP, e a partir do iOS 17 já tem suporte universal em Portugal (98,3% segundo o caniuse com filtro PT).

No `next.config.ts`, configurar o domain remote e o cache imutável:

// next.config.ts
import type { NextConfig } from "next";

const config: NextConfig = {
  images: {
    formats: ["image/avif", "image/webp"],
    minimumCacheTTL: 31536000, // 1 ano
    remotePatterns: [
      { protocol: "https", hostname: "cdn.exemplo.pt" },
    ],
  },
};
export default config;

Para o hero da homepage, recomendamos ainda servir uma variante específica para conexões 4G/5G via `Network Information API`, ou no mínimo um `blurDataURL` baseado em LQIP (Low Quality Image Placeholder) de ~20 bytes. Um cliente nosso de equipamento desportivo em Aveiro reduziu o LCP em telemóvel de 3,2 s para 1,7 s só com esta combinação.

3. Prevenir o CLS: carregamento de fontes e conteúdo dinâmico

O CLS (Cumulative Layout Shift) deve manter-se ≤ 0,1. Os dois grandes culpados em e-commerce português são: o flash de fonte sem estilo (FOUT) quando se carrega uma webfont da Google Fonts, e a injeção de banners (cookies, promoções, RGPD) sem reserva de espaço. A solução para fontes em Next.js 15 passa pelo `next/font`, que faz auto-hosting e gera `size-adjust` automaticamente:

// app/layout.tsx
import { Inter } from "next/font/google";

const inter = Inter({
  subsets: ["latin"],
  display: "swap",
  variable: "--font-inter",
  adjustFontFallback: true, // chave para CLS = 0
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="pt-PT" className={inter.variable}>
      <body>{children}</body>
    </html>
  );
}

Para conteúdo dinâmico — carrosséis, recomendações personalizadas, badges de stock — a regra de ouro é reservar sempre espaço com `min-height` ou `aspect-ratio` em CSS. Nunca usar `display: none` seguido de injeção tardia; preferir um skeleton com as dimensões finais já definidas. Para banners de consentimento RGPD (obrigatórios pela CNPD), colocá-los em `position: fixed` no fundo do viewport em vez de empurrarem o conteúdo é a abordagem que respeita simultaneamente o utilizador e o CLS.

Particularmente em PLPs (páginas de listagem) com lazy loading infinito, garantir que cada cartão de produto tem altura fixa antes da imagem carregar. Tipicamente isto faz-se com:

.product-card {
  aspect-ratio: 3 / 4;
  contain: layout style paint;
  content-visibility: auto;
  contain-intrinsic-size: 0 480px;
}

A combinação `content-visibility: auto` + `contain-intrinsic-size` permite ao browser saltar completamente o rendering de cartões fora do viewport, melhorando simultaneamente o LCP e o INP. Cuidado: `content-visibility` ainda não funciona perfeitamente no Safari iOS 16, mas com fallback gracioso é seguro usar em 2026.

4. Edge caching em Portugal: o factor Lisboa-node

Mesmo com tudo o resto perfeito, se o seu HTML é gerado em Frankfurt ou Paris, o utilizador no Algarve está a pagar 25-40 ms só de RTT. Os principais CDNs globais têm hoje POPs em Lisboa: Cloudflare desde 2019, Fastly desde 2022, Vercel Edge Network desde 2023 (parceiro AWS no datacenter de Sines), e AWS CloudFront com edge em Lisboa desde inícios de 2024. Aproveitar este edge é trivial mas frequentemente esquecido.

Com Next.js 15 a abordagem mais eficaz combina o ISR (Incremental Static Regeneration) com cache tags para invalidação cirúrgica:

// app/produto/[slug]/page.tsx
import { unstable_cache } from "next/cache";

const getProduct = unstable_cache(
  async (slug: string) => {
    const res = await fetch(`${process.env.API_URL}/products/${slug}`);
    return res.json();
  },
  ["product"],
  { revalidate: 3600, tags: ["products"] }
);

export const revalidate = 3600;
export const dynamic = "force-static";

Quando o stock muda, basta chamar `revalidateTag("products")` num webhook do PIM ou do ERP. O HTML servido a partir de Lisboa fica imediatamente actualizado, sem rebuild completo. Para componentes verdadeiramente dinâmicos — preço com IVA, stock, recomendações — usar a estratégia PPR (Partial Pre-Rendering) do Next.js 15, que serve o shell estático imediatamente do edge e hidrata as zonas dinâmicas em streaming. Resultado típico: TTFB < 100 ms para utilizadores em Portugal continental.

No `vercel.json` (ou equivalente para outros providers), forçar a região de execução para edge europeu:

{
  "functions": {
    "app/api/**": {
      "runtime": "edge",
      "regions": ["cdg1", "lhr1", "fra1"]
    }
  }
}

Não existe ainda região `lis1` em Vercel, mas o roteamento BGP a partir de `cdg1` (Paris) para Portugal continental tem latência média de 18 ms — suficiente para manter o TTFB confortavelmente abaixo do limiar verde. Se trabalha com volumes grandes, considere AWS Lambda@Edge directamente, que oferece edge functions executadas em Lisboa.

5. Ferramentas de monitorização: do laboratório ao campo

Existe uma diferença crítica entre dados de laboratório (lab) e dados de campo (field). O Lighthouse e o PageSpeed Insights dão-nos sintéticos úteis para detectar regressões, mas só o CrUX (Chrome User Experience Report) reflecte o que os utilizadores reais portugueses experimentam. A nossa stack de monitorização recomendada para 2026 combina três camadas:

1. CrUX API + BigQuery — para análise histórica do percentil 75 por país. A consulta segmentada por país=PRT permite ver tendências mês a mês especificamente para o mercado português:

SELECT
  yyyymm,
  origin,
  p75_inp,
  p75_lcp,
  p75_cls
FROM `chrome-ux-report.country_pt.YYYYMM`
WHERE origin = 'https://www.seu-site.pt'
ORDER BY yyyymm DESC
LIMIT 12;

2. RUM próprio — o snippet `web-vitals/attribution` mostrado na secção 1, enviando para um endpoint Next.js que armazena em ClickHouse ou Postgres. Permite cortar por device, browser, rota e versão de deploy. Útil para correlacionar uma subida do INP com um deploy específico.

3. Calibre, SpeedCurve ou DebugBear — monitorização sintética com testes diários a partir de Lisboa. O Calibre oferece um plano específico para PMEs portuguesas a partir de 79€/mês que cobre 5 URLs e dá alertas Slack quando o budget de performance é ultrapassado. É a forma mais barata de detectar regressões antes de chegarem a produção.

Definir performance budgets no CI/CD é não-negociável. Um workflow GitHub Actions simples com `@unlighthouse/cli` falha o build se o LCP exceder 1,8 s ou o INP exceder 200 ms num conjunto de URLs representativos. Este é o tipo de prática que o nosso serviço de desenvolvimento web implementa por defeito em qualquer novo projeto.

6. Caso de estudo: marca portuguesa de calçado, Q1 2026

Para tornar tudo isto concreto, partilhamos os resultados de uma intervenção que realizámos no primeiro trimestre de 2026 numa marca portuguesa de calçado (volume mensal de ~45.000 sessões, ticket médio 78€). O ponto de partida era um Shopify clássico migrado para um headstart customizado em Next.js 14, com os seguintes valores de baseline medidos via CrUX em Janeiro:

  • LCP (p75 mobile PT): 3,4 s — vermelho
  • INP (p75 mobile PT): 412 ms — vermelho
  • CLS (p75 mobile PT): 0,18 — laranja
  • Taxa de conversão mobile: 0,82%

Em seis semanas aplicámos exactamente o que está descrito neste artigo: upgrade para Next.js 15 com PPR, migração para AVIF servido via Cloudflare R2 com edge em Lisboa, refactor do botão "Adicionar ao carrinho" com `useTransition` e optimistic UI, substituição da webfont auto-hospedada com `adjustFontFallback`, e fragmentação do mega-menu com `scheduler.yield()`. Resultados medidos em Abril:

  • LCP (p75 mobile PT): 1,6 s — verde (-53%)
  • INP (p75 mobile PT): 142 ms — verde (-66%)
  • CLS (p75 mobile PT): 0,04 — verde (-78%)
  • Taxa de conversão mobile: 1,31% (+60%)
  • Impressões orgânicas (GSC): +34% em queries mobile não-marca

O ROI puro da intervenção, calculado sobre o aumento de receita atribuível ao crescimento de conversão, pagou-se em 38 dias. E o efeito SEO secundário — a Google premeia Core Web Vitals verdes com melhor posicionamento mobile — continuou a render frutos nos meses seguintes.

Conclusão: a janela está aberta, mas não por muito tempo

O e-commerce português está num momento raro: a maioria dos concorrentes ainda não percebeu a importância do INP e continua a culpar "a internet portuguesa" pelas más métricas. Quem agir nos próximos 6 meses ganha uma vantagem competitiva real, mensurável em milhões de euros para os players maiores e em pontos percentuais de conversão para as PMEs. O Next.js 15, o AVIF, o edge Lisboa e os padrões React modernos (Server Components, PPR, `useTransition`) tornam isto acessível a qualquer equipa de desenvolvimento competente.

Na Go To Agency trabalhamos com PMEs portuguesas e marcas internacionais com presença em Portugal para implementar exactamente este tipo de optimizações de raiz, do desenho técnico à monitorização contínua em produção. Se quer auditar os seus Core Web Vitals e perceber o potencial de ganho concreto para o seu site, peça-nos um orçamento ou conheça a nossa abordagem. A diferença entre um e-commerce que carrega em 1,5 s e um que carrega em 3,5 s é literalmente a diferença entre crescer ou estagnar em 2026.

RM

Sobre o autor

Robin Monteiro

Co-fondateur de Go To Agency

Développeur full-stack et co-fondateur de Go To Agency, Robin conçoit des solutions web performantes avec Next.js, React et les dernières technologies.

Conhecer a equipa

Precisa de ajuda com o seu projeto?

Falemos do seu projeto gratuitamente. Auditoria, conselhos e recomendações personalizadas em 15 minutos.

Partilhar artigo

Questions fréquentes

Qual é o limiar do INP para ser considerado verde em 2026?+

O INP (Interaction to Next Paint) deve manter-se igual ou inferior a 200 ms no percentil 75 das sessões para ser classificado como bom pela Google. Entre 200 e 500 ms é considerado a precisar de melhoria (laranja), e acima de 500 ms é mau (vermelho). Em e-commerce português a referência prática para se destacar é manter-se abaixo dos 150 ms.

O Next.js 15 e o PPR funcionam bem em Portugal sem região edge Lisboa nativa?+

Sim. Apesar de Vercel não ter ainda uma região lis1 oficial, o roteamento BGP a partir de cdg1 (Paris) para Portugal continental dá latência média de 18 ms. Combinado com o PPR (Partial Pre-Rendering), o TTFB para utilizadores em Lisboa, Porto ou Coimbra mantém-se confortavelmente abaixo dos 100 ms. Para volumes maiores, AWS Lambda@Edge tem POP nativo em Lisboa desde 2024.

AVIF vale a pena em Portugal ou WebP ainda é suficiente?+

AVIF vale claramente a pena. Com o suporte do iOS 17+ e de todos os Chromium-based, a cobertura em Portugal é de 98,3% segundo o caniuse filtrado por PT. O ganho médio de bytes face ao WebP é de 35-50%, o que tem impacto directo no LCP em ligações 4G. O Next.js Image serve AVIF para browsers compatíveis e WebP em fallback automaticamente.

Quanto custa implementar monitorização Core Web Vitals com RUM próprio?+

Para uma PME portuguesa, a stack mínima viável (web-vitals + endpoint Next.js + Postgres ou ClickHouse) tem custo de infra-estrutura inferior a 30€/mês. Soluções geridas como Calibre ou SpeedCurve começam nos 79€/mês para 5 URLs. A nossa recomendação é combinar RUM próprio (gratuito, dados reais) com Calibre para alertas e tendências históricas.

Artigos relacionados

Orçamento gratuito
Core Web Vitals 2026 E-commerce Portugal — INP LCP CLS | Go To Agency