Back

Consejos Prácticos de Frontend para Mejorar las Puntuaciones de Core Web Vitals

Consejos Prácticos de Frontend para Mejorar las Puntuaciones de Core Web Vitals

Lograr que las puntuaciones de Core Web Vitals superen los umbrales de Google no requiere una reestructuración completa de la infraestructura. La mayoría de las mejoras de rendimiento provienen de optimizaciones inteligentes de frontend que cualquier desarrollador puede implementar. Aquí te mostramos cómo abordar las mejoras más impactantes para LCP, INP y CLS sin tocar tu backend.

Puntos Clave

  • Prioriza el contenido principal con fetchpriority y sugerencias de preload para mejorar el LCP
  • Divide las tareas largas de JavaScript usando scheduler.yield() para mejorar el INP
  • Reserva espacio para todo el contenido dinámico para prevenir el CLS
  • Las pequeñas optimizaciones de frontend pueden cambiar las puntuaciones de fallidas a aprobadas

Optimizando el Rendimiento del LCP: Haz que tu Contenido Principal Sea Ultrarrápido

Tu Largest Contentful Paint típicamente involucra imágenes principales o bloques de texto above-the-fold. La clave está en hacer que estos recursos sean detectables y priorizados desde el inicio.

Manejo Inteligente de Imágenes para Mejorar el LCP

<!-- Antes: Oculto del escáner de preload del navegador -->
<div class="hero" style="background-image: url('hero.jpg')"></div>

<!-- Después: Detectable y priorizado -->
<img src="hero.webp" 
     fetchpriority="high"
     width="1200" 
     height="600"
     alt="Imagen principal">

Para imágenes críticas cargadas mediante JavaScript, agrega una sugerencia de preload:

<link rel="preload" as="image" href="hero.webp" fetchpriority="high">

Técnicas de Priorización de Recursos

Los navegadores modernos soportan fetchpriority para potenciar recursos críticos:

// Despriorizar imágenes no críticas
document.querySelectorAll('img[loading="lazy"]').forEach(img => {
  img.fetchPriority = 'low';
});

Elimina cualquier atributo loading="lazy" de las imágenes LCP—retrasan la carga innecesariamente. Además, asegúrate de que tu recurso LCP se cargue desde la respuesta HTML inicial, no después de la ejecución de JavaScript.

Dividiendo Tareas Largas para Mejorar el Rendimiento del INP

El INP mide qué tan rápido responde tu página a todas las interacciones del usuario, no solo a la primera. Las tareas largas de JavaScript son el principal culpable detrás de las puntuaciones pobres de INP.

Patrones de Programación de Tareas

// Antes: Bloqueando el hilo principal
function processData(items) {
  items.forEach(item => {
    // Procesamiento pesado
    complexCalculation(item);
    updateUI(item);
  });
}

// Después: Cediendo el control al navegador
async function processData(items) {
  for (const item of items) {
    complexCalculation(item);
    updateUI(item);
    
    // Ceder el control de vuelta al navegador
    await scheduler.yield();
  }
}

Para navegadores sin soporte de scheduler.yield(), usa este respaldo:

function yieldToMain() {
  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

Optimizar Manejadores de Eventos

Agrupa las operaciones del DOM y evita el layout thrashing:

// Ineficiente: Fuerza múltiples reflows
elements.forEach(el => {
  el.style.left = el.offsetLeft + 10 + 'px';
});

// Eficiente: Lee todo, luego escribe todo
const positions = elements.map(el => el.offsetLeft);
elements.forEach((el, i) => {
  el.style.left = positions[i] + 10 + 'px';
});

Previniendo Cambios de Layout: Reserva Espacio y Evita Reflows

Las correcciones de CLS a menudo requieren menos código pero más disciplina. Cada elemento dinámico necesita espacio reservado.

Dimensiones de Imágenes y Medios

<!-- Siempre especifica dimensiones -->
<img src="product.jpg" width="400" height="300" alt="Producto">

<!-- Para imágenes responsivas, usa aspect-ratio -->
<style>
.responsive-image {
  width: 100%;
  aspect-ratio: 16/9;
}
</style>

Patrones de Contenido Dinámico

Para contenido que se carga después del renderizado inicial:

/* Reserva espacio mínimo para contenido dinámico */
.ad-container {
  min-height: 250px;
}

.comments-section {
  min-height: 400px;
}

/* Las pantallas skeleton previenen cambios */
.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: loading 1.5s infinite;
}

Mejores Prácticas de Animación

Nunca animes propiedades que desencadenen layout:

/* Causa cambios de layout */
.slide-in {
  animation: slideIn 0.3s;
}
@keyframes slideIn {
  from { margin-left: -100%; }
  to { margin-left: 0; }
}

/* Sin cambios de layout */
.slide-in {
  animation: slideIn 0.3s;
}
@keyframes slideIn {
  from { transform: translateX(-100%); }
  to { transform: translateX(0); }
}

Lista de Verificación de Victorias Rápidas

Para optimización de LCP:

  • Agrega fetchpriority="high" a las imágenes principales
  • Elimina lazy loading del contenido above-the-fold
  • Precarga fuentes e imágenes críticas
  • Incluye CSS crítico inline

Para rendimiento de INP:

  • Divide tareas de más de 50ms con scheduler.yield()
  • Aplica debounce a los manejadores de entrada
  • Mueve cálculos pesados a Web Workers
  • Usa transformaciones CSS en lugar de animaciones JavaScript

Para correcciones de CLS:

  • Establece dimensiones explícitas en todas las imágenes y videos
  • Reserva espacio para contenido dinámico con min-height
  • Usa transformaciones CSS para animaciones
  • Precarga fuentes web con font-display: optional

Conclusión

Mejorar las Core Web Vitals no requiere cambios arquitectónicos o infraestructura costosa. Enfócate en hacer que tu contenido principal sea detectable y priorizado, dividir las tareas de JavaScript para mantener el hilo principal responsivo, y reservar espacio para cada pieza de contenido dinámico. Estas optimizaciones de frontend por sí solas pueden mover tus puntuaciones de rojo a verde—y más importante, entregar la experiencia rápida y estable que tus usuarios merecen.

Preguntas Frecuentes

Las optimizaciones de frontend pueden mejorar dramáticamente las puntuaciones. La mayoría de los sitios que fallan pueden alcanzar umbrales de aprobación solo implementando priorización de imágenes, programación de tareas y correcciones de estabilidad de layout. Estos cambios a menudo mejoran el LCP en 30-50%, reducen el INP a menos de 200ms, y eliminan la mayoría de problemas de CLS.

Usa scheduler.yield() cuando esté disponible ya que está específicamente diseñado para programación de tareas. Para mayor compatibilidad con navegadores, setTimeout con delay de 0ms funciona como respaldo. La clave es ceder el control de vuelta al navegador cada 50ms para mantener la responsividad.

Dimensionar y priorizar apropiadamente tu elemento LCP típicamente proporciona la mayor mejora. Agregar fetchpriority high a tu imagen principal y eliminar lazy loading del contenido above-the-fold puede reducir el tiempo de LCP a la mitad en muchos sitios.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay