Volver al blog

Diseño y desarrollo web

Core Web Vitals 2026: Guía de Optimización Next.js y React

Imagen destacada del artículo: core web vitals 2026 nextjs react

Core Web Vitals 2026: Optimización para Next.js y React

Los Core Web Vitals han evolucionado significativamente desde su introducción en 2020. En 2026, con la consolidación de INP (Interaction to Next Paint) como métrica oficial y las capacidades avanzadas de Next.js 15, optimizar el rendimiento web requiere un enfoque completamente renovado. Esta guía técnica te muestra exactamente cómo dominar cada métrica utilizando las herramientas más modernas del ecosistema React.

¿Quieres que lo hagamos por ti? Mira nuestro servicio de Desarrollo WordPress

Google ha confirmado que los sitios que superan los umbrales de Core Web Vitals tienen un 24% menos de abandono y mejores posiciones en los resultados de búsqueda. Para proyectos desarrollados con React y Next.js, las oportunidades de optimización son enormes, pero también lo son los desafíos técnicos.

¿Qué son los Core Web Vitals en 2026 y por qué importan?

Los Core Web Vitals son un conjunto de métricas centradas en el usuario que miden la experiencia real de carga, interactividad y estabilidad visual de una página web. En 2026, las tres métricas fundamentales son:

  • LCP (Largest Contentful Paint): Tiempo hasta que el elemento más grande del viewport es visible
  • INP (Interaction to Next Paint): Latencia de todas las interacciones del usuario
  • CLS (Cumulative Layout Shift): Estabilidad visual durante toda la sesión

A diferencia de métricas sintéticas como Time to First Byte o Speed Index, los Core Web Vitals reflejan la experiencia percibida por usuarios reales navegando en condiciones reales de red y dispositivo.

Umbrales actualizados para 2026

MétricaBuenoNecesita mejoraPobre
LCP≤ 2.5s2.5s - 4.0s> 4.0s
INP≤ 200ms200ms - 500ms> 500ms
CLS≤ 0.10.1 - 0.25> 0.25

El cambio más significativo fue la sustitución de FID (First Input Delay) por INP en marzo de 2024. Mientras FID solo medía la primera interacción, INP evalúa la latencia de todas las interacciones durante la sesión, ofreciendo una visión mucho más realista de la interactividad.

¿Cómo funciona LCP y cómo optimizarlo en Next.js 15?

LCP mide el tiempo que tarda en renderizarse el elemento de contenido más grande visible en el viewport. Típicamente, este elemento es una imagen hero, un bloque de texto prominente o un video poster.

Elementos que califican para LCP

  • Elementos <img> (incluyendo dentro de <picture>)
  • Imágenes de fondo cargadas via url() en CSS
  • Elementos <video> con poster
  • Elementos de texto (<h1>, <p>, etc.) con contenido significativo
  • Elementos con imágenes de fondo inline

Técnicas de optimización LCP en Next.js 15

1. Uso correcto del componente Image

Next.js 15 incluye un componente Image optimizado que implementa lazy loading inteligente, pero para el elemento LCP necesitamos el comportamiento opuesto:

// app/page.tsx
import Image from 'next/image';

export default function HomePage() {
  return (
    <main>
      <section className="hero">
        {/* Imagen LCP: priority + fetchPriority */}
        <Image
          src="/hero-banner.webp"
          alt="Descripción del hero"
          width={1920}
          height={1080}
          priority // Desactiva lazy loading
          fetchPriority="high" // Hint al navegador
          sizes="100vw"
          quality={85}
        />
      </section>
    
      {/* Resto de imágenes: lazy loading por defecto */}
      <Image
        src="/secondary-image.webp"
        alt="Imagen secundaria"
        width={800}
        height={600}
        loading="lazy"
      />
    </main>
  );
}

2. Preload de recursos críticos

En el App Router de Next.js 15, puedes gestionar preloads directamente en el layout:

// app/layout.tsx
import { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Mi Sitio Web',
  other: {
    'link': [
      {
        rel: 'preload',
        href: '/fonts/inter-var.woff2',
        as: 'font',
        type: 'font/woff2',
        crossOrigin: 'anonymous',
      },
    ],
  },
};

// O usando el head
export default function RootLayout({ children }) {
  return (
    <html lang="es">
      <head>
        <link
          rel="preload"
          href="/hero-banner.webp"
          as="image"
          fetchPriority="high"
        />
        <link
          rel="preconnect"
          href="https://fonts.googleapis.com"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

3. Streaming y Suspense para LCP

Una técnica avanzada es usar Suspense para priorizar el contenido LCP:

// app/page.tsx
import { Suspense } from 'react';
import HeroBanner from '@/components/HeroBanner';
import DynamicContent from '@/components/DynamicContent';

export default function Page() {
  return (
    <>
      {/* Contenido LCP renderiza inmediatamente */}
      <HeroBanner />
    
      {/* Contenido secundario en streaming */}
      <Suspense fallback={<ContentSkeleton />}>
        <DynamicContent />
      </Suspense>
    </>
  );
}

¿Qué es INP y por qué reemplazó a FID?

INP (Interaction to Next Paint) mide la latencia entre una interacción del usuario y el siguiente frame visual actualizado. A diferencia de FID, que solo consideraba la primera interacción, INP evalúa todas las interacciones y reporta un valor cercano al peor caso.

Anatomía de una interacción

Cada interacción tiene tres fases:

  1. Input delay: Tiempo desde el evento hasta que comienza el handler
  2. Processing time: Tiempo ejecutando los event handlers
  3. Presentation delay: Tiempo hasta que el navegador renderiza el frame
[Click] → [Input Delay] → [Processing] → [Presentation] → [Visual Update]
         └─────────────── INP Total ───────────────────┘

Interacciones que cuenta INP

  • Clicks del mouse
  • Taps en pantallas táctiles
  • Pulsaciones de teclas (tanto físicas como de teclado en pantalla)

No cuenta: Hover, scroll o zoom (considerados interacciones continuas).

Optimización INP en React y Next.js

1. Evitar bloqueos del main thread

El problema más común de INP en React son renders síncronos extensos:

// ❌ MAL: Re-render costoso bloquea interacciones
function ProductList({ products }) {
  const [filter, setFilter] = useState('');

  // Filtrado síncrono en cada render
  const filtered = products.filter(p => 
    p.name.toLowerCase().includes(filter.toLowerCase())
  );

  return (
    <>
      <input 
        value={filter} 
        onChange={e => setFilter(e.target.value)} 
      />
      {filtered.map(p => <ProductCard key={p.id} product={p} />)}
    </>
  );
}

// ✅ BIEN: useDeferredValue para priorizar input
import { useDeferredValue, useMemo } from 'react';

function ProductList({ products }) {
  const [filter, setFilter] = useState('');
  const deferredFilter = useDeferredValue(filter);

  const filtered = useMemo(() => 
    products.filter(p => 
      p.name.toLowerCase().includes(deferredFilter.toLowerCase())
    ),
    [products, deferredFilter]
  );

  const isStale = filter !== deferredFilter;

  return (
    <>
      <input 
        value={filter} 
        onChange={e => setFilter(e.target.value)} 
      />
      <div style={{ opacity: isStale ? 0.7 : 1 }}>
        {filtered.map(p => <ProductCard key={p.id} product={p} />)}
      </div>
    </>
  );
}

2. useTransition para actualizaciones no urgentes

import { useState, useTransition } from 'react';

function TabContainer() {
  const [tab, setTab] = useState('home');
  const [isPending, startTransition] = useTransition();

  function handleTabChange(nextTab) {
    startTransition(() => {
      setTab(nextTab);
    });
  }

  return (
    <div>
      <nav>
        {['home', 'products', 'about'].map(t => (
          <button
            key={t}
            onClick={() => handleTabChange(t)}
            className={tab === t ? 'active' : ''}
          >
            {t}
          </button>
        ))}
      </nav>
    
      <div style={{ opacity: isPending ? 0.8 : 1 }}>
        <TabContent tab={tab} />
      </div>
    </div>
  );
}

3. Virtualización para listas largas

import { useVirtualizer } from '@tanstack/react-virtual';

function VirtualizedList({ items }) {
  const parentRef = useRef(null);

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 80,
    overscan: 5,
  });

  return (
    <div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
      <div
        style={{
          height: `${virtualizer.getTotalSize()}px`,
          position: 'relative',
        }}
      >
        {virtualizer.getVirtualItems().map(virtualItem => (
          <div
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              transform: `translateY(${virtualItem.start}px)`,
              height: `${virtualItem.size}px`,
            }}
          >
            <ItemCard item={items[virtualItem.index]} />
          </div>
        ))}
      </div>
    </div>
  );
}

¿Cómo prevenir CLS en aplicaciones React modernas?

CLS (Cumulative Layout Shift) mide los cambios inesperados en el layout durante toda la vida de la página. Un CLS alto frustra a los usuarios que intentan interactuar con elementos que se mueven.

Causas comunes de CLS

  1. Imágenes sin dimensiones: El navegador no reserva espacio hasta que descarga la imagen
  2. Anuncios y embeds dinámicos: Contenido inyectado que desplaza el layout
  3. Fuentes web (FOIT/FOUT): Cambios de tamaño al cargar fuentes
  4. Contenido insertado dinámicamente: Banners, notificaciones, modales

Soluciones específicas para Next.js 15

1. Aspect ratio para media

// Componente de imagen con aspect ratio garantizado
function ResponsiveImage({ src, alt, aspectRatio = '16/9' }) {
  return (
    <div style={{ aspectRatio, position: 'relative' }}>
      <Image
        src={src}
        alt={alt}
        fill
        style={{ objectFit: 'cover' }}
        sizes="(max-width: 768px) 100vw, 50vw"
      />
    </div>
  );
}

2. Skeleton loaders con dimensiones fijas

// components/ProductSkeleton.tsx
export function ProductSkeleton() {
  return (
    <div className="product-card" style={{ height: '320px' }}>
      <div 
        className="skeleton" 
        style={{ height: '200px', background: '#e0e0e0' }} 
      />
      <div 
        className="skeleton" 
        style={{ height: '24px', marginTop: '16px', width: '80%' }} 
      />
      <div 
        className="skeleton" 
        style={{ height: '20px', marginTop: '8px', width: '40%' }} 
      />
    </div>
  );
}

// Uso con Suspense
import { Suspense } from 'react';

export default function ProductPage() {
  return (
    <Suspense fallback={<ProductSkeleton />}>
      <ProductDetails />
    </Suspense>
  );
}

3. Optimización de fuentes en Next.js 15

// app/layout.tsx
import { Inter, Roboto_Mono } from 'next/font/google';

const inter = Inter({
  subsets: ['latin'],
  display: 'swap', // Evita FOIT
  variable: '--font-inter',
  preload: true,
  fallback: ['system-ui', 'sans-serif'],
  adjustFontFallback: true, // Ajusta métricas del fallback
});

const robotoMono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-mono',
});

export default function RootLayout({ children }) {
  return (
    <html lang="es" className={`${inter.variable} ${robotoMono.variable}`}>
      <body className={inter.className}>
        {children}
      </body>
    </html>
  );
}

4. Reservar espacio para contenido dinámico

// Componente de banner con altura reservada
function PromoBanner() {
  const [isVisible, setIsVisible] = useState(true);

  if (!isVisible) {
    // Mantener el espacio o colapsar suavemente
    return null;
  }

  return (
    <div 
      className="promo-banner"
      style={{ 
        minHeight: '60px', // Altura reservada
        containIntrinsicSize: '0 60px', // content-visibility optimization
      }}
    >
      <p>¡Oferta especial! 20% de descuento</p>
      <button onClick={() => setIsVisible(false)}>×</button>
    </div>
  );
}

¿Cómo impactan los React Server Components en Core Web Vitals?

Los React Server Components (RSC), completamente integrados en Next.js 15 App Router, transforman fundamentalmente cómo optimizamos Core Web Vitals. Al ejecutarse exclusivamente en el servidor, reducen drásticamente el JavaScript enviado al cliente.

Beneficios de RSC para cada métrica

LCP: Renderizado instantáneo

// app/products/[id]/page.tsx
// Este componente es un Server Component por defecto

import { getProduct } from '@/lib/api';
import ProductImage from '@/components/ProductImage';

export default async function ProductPage({ params }) {
  // Fetch en el servidor - sin waterfall en cliente
  const product = await getProduct(params.id);

  return (
    <article>
      {/* HTML completo enviado en la respuesta inicial */}
      <ProductImage 
        src={product.image} 
        alt={product.name}
        priority 
      />
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    
      {/* Solo este componente necesita JavaScript */}
      <AddToCartButton productId={product.id} />
    </article>
  );
}

INP: Menos JavaScript = menos bloqueos

// Comparación de bundles

// ❌ Enfoque tradicional (Client Component completo)
// Bundle: ~150KB de JavaScript
'use client';
import { useState, useEffect } from 'react';
import { formatPrice, calculateDiscount } from '@/lib/utils';
import { fetchReviews } from '@/lib/api';

function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);
  const [reviews, setReviews] = useState([]);

  useEffect(() => {
    // Fetches en cascada en el cliente
  }, [productId]);

  // Todo el código de formateo se envía al cliente
}

// ✅ Enfoque RSC híbrido
// Bundle: ~15KB de JavaScript (solo interactividad)

// Server Component - 0KB al cliente
async function ProductPage({ params }) {
  const [product, reviews] = await Promise.all([
    getProduct(params.id),
    getReviews(params.id),
  ]);

  // Formateo ejecutado en servidor
  const formattedPrice = formatPrice(product.price);
  const discount = calculateDiscount(product);

  return (
    <article>
      <h1>{product.name}</h1>
      <p className="price">{formattedPrice}</p>
    
      {/* Solo componentes interactivos son Client Components */}
      <InteractiveGallery images={product.images} />
      <AddToCartButton product={product} />
    
      {/* Reviews renderizadas en servidor */}
      <ReviewList reviews={reviews} />
    </article>
  );
}

Patrón de composición óptimo

// app/dashboard/page.tsx
import { Suspense } from 'react';
import DashboardHeader from '@/components/DashboardHeader';
import StatsCards from '@/components/StatsCards';
import RecentActivity from '@/components/RecentActivity';
import InteractiveChart from '@/components/InteractiveChart';

export default function DashboardPage() {
  return (
    <div className="dashboard">
      {/* Server Component - renderizado instantáneo */}
      <DashboardHeader />
    
      {/* Server Component con datos - streaming */}
      <Suspense fallback={<StatsCardsSkeleton />}>
        <StatsCards />
      </Suspense>
    
      {/* Client Component - carga diferida */}
      <Suspense fallback={<ChartSkeleton />}>
        <InteractiveChart />
      </Suspense>
    
      {/* Server Component - streaming paralelo */}
      <Suspense fallback={<ActivitySkeleton />}>
        <RecentActivity />
      </Suspense>
    </div>
  );
}

¿Qué herramientas usar para medir Core Web Vitals?

La medición precisa requiere combinar datos de laboratorio (sintéticos) con datos de campo (usuarios reales).

Herramientas de laboratorio

Lighthouse en Next.js

# Instalar Lighthouse CI
npm install -g @lhci/cli

# Configuración: lighthouserc.js
module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npm run start',
      url: ['http://localhost:3000/', 'http://localhost:3000/productos'],
      numberOfRuns: 3,
    },
    assert: {
      assertions: {
        'categories:performance': ['error', { minScore: 0.9 }],
        'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
        'interactive': ['error', { maxNumericValue: 3800 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

# Ejecutar en CI/CD
lhci autorun

Chrome DevTools Performance

  1. Abre DevTools → Performance
  2. Activa "Web Vitals" en el panel
  3. Habilita "CPU throttling: 4x slowdown"
  4. Habilita "Network: Slow 3G"
  5. Graba una sesión de usuario

Herramientas de campo (RUM)

web-vitals library

// lib/analytics.ts
import { onLCP, onINP, onCLS, Metric } from 'web-vitals';

function sendToAnalytics(metric: Metric) {
  const body = JSON.stringify({
    name: metric.name,
    value: metric.value,
    rating: metric.rating,
    delta: metric.delta,
    id: metric.id,
    navigationType: metric.navigationType,
  });

  // Usar sendBeacon para no bloquear unload
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/api/vitals', body);
  } else {
    fetch('/api/vitals', { body, method: 'POST', keepalive: true });
  }
}

export function initWebVitals() {
  onLCP(sendToAnalytics);
  onINP(sendToAnalytics);
  onCLS(sendToAnalytics);
}
// app/layout.tsx
'use client';
import { useEffect } from 'react';
import { initWebVitals } from '@/lib/analytics';

export function WebVitalsReporter() {
  useEffect(() => {
    initWebVitals();
  }, []);

  return null;
}

Google Search Console y CrUX

El Chrome User Experience Report (CrUX) proporciona datos reales de millones de usuarios Chrome. Accede a través de:

  • Search Console: Core Web Vitals report por URL/grupo
  • PageSpeed Insights: Datos CrUX + diagnóstico Lighthouse
  • CrUX Dashboard: Visualizaciones en Data Studio
  • BigQuery: Consultas SQL sobre el dataset público
-- Consulta CrUX en BigQuery
SELECT
  origin,
  p75_lcp,
  p75_inp,
  p75_cls
FROM
  `chrome-ux-report.materialized.metrics_summary`
WHERE
  origin = 'https://tudominio.com'
  AND yyyymm = 202601

Next.js Analytics (Vercel)

// next.config.js
module.exports = {
  experimental: {
    webVitalsAttribution: ['CLS', 'LCP', 'INP'],
  },
};

// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <SpeedInsights />
      </body>
    </html>
  );
}

¿Cuáles son los benchmarks de Core Web Vitals por tipo de sitio?

Los umbrales universales de Google no cuentan toda la historia. Diferentes tipos de sitios tienen desafíos únicos y expectativas distintas.

E-commerce

MétricaBenchmark competitivoTop 10%
LCP< 2.0s< 1.5s
INP< 150ms< 100ms
CLS< 0.05< 0.02

Desafíos específicos:

  • Carruseles de productos (CLS)
  • Filtros dinámicos (INP)
  • Imágenes de alta calidad (LCP)

SaaS / Dashboards

MétricaBenchmark competitivoTop 10%
LCP< 2.5s< 1.8s
INP< 100ms< 50ms
CLS< 0.05< 0.01

Desafíos específicos:

  • Gráficos interactivos complejos (INP)
  • Actualizaciones en tiempo real (CLS)
  • Tablas con muchos datos (INP, LCP)

Blogs / Content sites

MétricaBenchmark competitivoTop 10%
LCP< 1.8s< 1.2s
INP< 200ms< 150ms
CLS< 0.1< 0.05

Desafíos específicos:

  • Imágenes hero grandes (LCP)
  • Anuncios y embeds (CLS)
  • Lazy loading de contenido (CLS)

Landing pages

MétricaBenchmark competitivoTop 10%
LCP< 1.5s< 1.0s
INP< 150ms< 100ms
CLS< 0.020

Desafíos específicos:

  • Animaciones de entrada (CLS)
  • Videos autoplay (LCP)
  • CTAs interactivos (INP)

¿Cómo implementar un pipeline de monitoreo continuo?

La optimización de Core Web Vitals no es un esfuerzo único. Requiere monitoreo continuo y alertas tempranas.

GitHub Actions para CI/CD

# .github/workflows/lighthouse.yml
name: Lighthouse CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
    
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
    
      - name: Install dependencies
        run: npm ci
    
      - name: Build
        run: npm run build
    
      - name: Run Lighthouse
        uses: treosh/lighthouse-ci-action@v11
        with:
          configPath: './lighthouserc.js'
          uploadArtifacts: true
          temporaryPublicStorage: true
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
    
      - name: Comment PR with results
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const results = JSON.parse(
              fs.readFileSync('.lighthouseci/manifest.json', 'utf8')
            );
            // Generar comentario con métricas

Dashboard de monitoreo personalizado

Para proyectos enterprise, nuestro equipo de desarrollo Node.js implementa dashboards de monitoreo con:

  • Alertas Slack/Email cuando métricas degradan
  • Comparativas históricas por release
  • Segmentación por tipo de página y dispositivo
  • Correlación con métricas de negocio

Conclusión: El rendimiento como ventaja competitiva

Optimizar Core Web Vitals en 2026 requiere entender profundamente las métricas, dominar las herramientas de React y Next.js, y mantener un proceso de monitoreo continuo. Los sitios que invierten en rendimiento ven mejoras tangibles en SEO, conversiones y satisfacción del usuario.

Las técnicas cubiertas en este artículo, desde React Server Components hasta virtualización e INP optimization, representan el estado del arte en desarrollo web performante. Implementarlas correctamente requiere experiencia en arquitectura frontend y comprensión del comportamiento real de los usuarios.

¿Tu sitio Next.js necesita optimización de Core Web Vitals? En KIWOP somos especialistas en desarrollo React y optimización de rendimiento. Contacta con nuestro equipo para una auditoría gratuita de tu sitio.

Preguntas frecuentes sobre Core Web Vitals

¿Cuál es la diferencia entre INP y FID?

FID (First Input Delay) solo medía la latencia de la primera interacción del usuario con la página. INP (Interaction to Next Paint) evalúa todas las interacciones durante toda la sesión y reporta un valor representativo del peor caso (percentil 75). Esto significa que INP es una métrica mucho más exigente y realista de la interactividad percibida.

¿Los Core Web Vitals afectan directamente al ranking en Google?

Sí, los Core Web Vitals son un factor de ranking confirmado desde 2021. Sin embargo, Google ha clarificado que el contenido relevante y de calidad sigue siendo más importante. Los Core Web Vitals actúan como "desempate" entre páginas con contenido similar, y como barrera de entrada para posiciones premium.

¿Cómo afectan los React Server Components al LCP?

Los React Server Components mejoran significativamente el LCP porque el HTML se genera completamente en el servidor y se envía en la respuesta inicial. No hay waterfall de JavaScript → fetch → render en el cliente. El contenido LCP está presente desde el primer byte de HTML.

¿Qué es un buen score de INP para un e-commerce?

Para e-commerce competitivo, recomendamos un INP inferior a 150ms (el umbral "bueno" de Google es 200ms). Los top performers logran menos de 100ms. Las áreas críticas son filtros de productos, carruseles y procesos de checkout.

¿El CLS se mide durante toda la sesión o solo en la carga inicial?

CLS se mide durante toda la vida de la página, pero Google usa "session windows" para el cálculo final. Un session window es un grupo de shifts con menos de 1 segundo entre ellos y máximo 5 segundos de duración. El CLS reportado es el máximo de todos los session windows.

¿Next.js 15 tiene optimizaciones automáticas para Core Web Vitals?

Sí. Next.js 15 incluye: optimización automática de imágenes (WebP/AVIF, lazy loading, dimensiones), optimización de fuentes (preload, font-display), prefetching inteligente de rutas, y React Server Components por defecto que reducen el JavaScript enviado al cliente.

¿Cómo puedo medir Core Web Vitals de usuarios reales, no solo Lighthouse?

Usa la librería web-vitals de Google para capturar métricas RUM (Real User Monitoring). Combínala con tu stack de analytics existente o servicios como Vercel Analytics, Datadog RUM, o New Relic Browser. Los datos de CrUX en Search Console también muestran métricas de usuarios Chrome reales.

¿Vale la pena optimizar para el percentil 75 o debo apuntar al 95?

Google usa el percentil 75 (p75) para sus umbrales, lo que significa que el 75% de tus usuarios debe experimentar buenos valores. Sin embargo, para sitios premium, optimizar para p90 o p95 garantiza una experiencia consistente incluso para usuarios en condiciones adversas (conexiones lentas, dispositivos antiguos).

¿Necesitas una web profesional a medida?

Desarrollamos sitios web con WordPress optimizados para rendimiento, SEO y conversión.

Descubre nuestro servicio de Desarrollo WordPress

Hablemos.

Consulta técnica inicial

IA, seguridad y rendimiento. Diagnóstico y propuesta cerrada por fases.

  • NDA disponible
  • Respuesta <24h
  • Propuesta por fases

Tu primera reunión es con un Arquitecto de Soluciones, no con un comercial.

Hablar con un arquitecto