Optimiza el retraso de renderizado del elemento LCP

De descargado a mostrado: aprende a mejorar la parte del retraso de renderizado del elemento del Largest Contentful Paint.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-07-10

Esta guía es parte de la sección Largest Contentful Paint (LCP) de nuestro centro de recursos de Core Web Vitals. El Element Render Delay es la fase final en la línea de tiempo del LCP. Representa el tiempo entre que el recurso del LCP termina de descargarse y que se pinta de forma visible en la pantalla.

Optimiza el Element Render Delay del LCP

De las cuatro fases del LCP, el Element Render Delay es la más incomprendida. Los equipos optimizan el TTFB, eliminan el Resource Load Delay y comprimen los recursos para acortar el Resource Load Duration. Ven terminar la cascada de red y asumen que el trabajo está hecho. Se equivocan.

El Element Render Delay es el tiempo desde que el recurso del LCP termina de descargarse hasta que el elemento se pinta por completo en la pantalla del usuario. Este no es un problema de red; es un problema del main thread. Un retraso de renderizado alto significa que el navegador tiene la imagen o la fuente, pero está demasiado ocupado con otras tareas para dibujarla realmente. Este retraso es un impuesto directo a tu puntuación del LCP. A veces añade 200 ms o más después de que se completan todas las solicitudes de red.

Definición precisa: El problema de la última milla

El Element Render Delay comienza en el momento en que el último byte del recurso del LCP (por ejemplo, un archivo de imagen o una fuente web) llega al navegador. Termina cuando el elemento del LCP se pinta de forma visible en la pantalla. Es, literalmente, el paso final.

Para los elementos del LCP basados en texto que usan una fuente del sistema, este retraso suele ser cero, ya que no se necesita un recurso externo. Sin embargo, para la gran mayoría de sitios donde el elemento del LCP es una imagen o usa una fuente web personalizada, esta fase suele ser el mayor cuello de botella. El navegador dedica este tiempo a tareas de CPU: traducir los bits descargados en píxeles visibles.

El 'por qué': Una línea de montaje atascada

Para corregir el retraso de renderizado, debes entender cómo el navegador dibuja una página. Es un proceso de múltiples etapas que a menudo se llama Critical Rendering Path. Piénsalo como una línea de montaje de una fábrica:

  1. Construcción de los planos (DOM y CSSOM): El navegador analiza el HTML para construir el Document Object Model (DOM) y el CSS para construir el CSS Object Model (CSSOM). Estos son los planos para el contenido y el estilo de la página.
  2. Combinación de planos (Render Tree): El DOM y el CSSOM se combinan en un Render Tree, que contiene solo los nodos necesarios para renderizar la página. Se omiten elementos como <head> o aquellos con display: none;.
  3. Cálculo de geometría (Layout): El navegador calcula el tamaño y la posición exactos de cada elemento en el render tree. A esta etapa también se le conoce como "reflow".
  4. Coloreado de los píxeles (Paint): El navegador rellena los píxeles de cada elemento. Tiene en cuenta el texto, los colores, las imágenes, los bordes y las sombras.
  5. Ensamblaje de capas (Composite): La página se dibuja en diferentes capas, que luego se ensamblan en el orden correcto para crear la imagen final de la pantalla.

El Element Render Delay es el tiempo que consumen estas etapas finales: Layout, Paint y Composite. Toda esta línea de montaje la dirige un solo trabajador: el main thread. Si ese trabajador está ocupado ejecutando un long task de JavaScript o analizando un archivo CSS enorme, la línea de montaje se detiene. La imagen del LCP puede haber llegado, pero está en el muelle de carga esperando a que el main thread se libere para procesarla y pintarla.

Cómo localizar el Element Render Delay

El diagnóstico de este problema sigue un proceso estricto de dos pasos. No te saltes el primer paso.

Paso 1: Valida con field data (RUM)
Antes de abrir DevTools, debes confirmar que el Element Render Delay es un problema real para tus usuarios. Una herramienta de Real User Monitoring (RUM) profesional como la mía, CoreDash, es esencial. Desglosará el LCP de tu sitio en sus cuatro subpartes. Si tus datos RUM muestran un Element Render Delay significativo en el percentil 75, tienes un problema validado y de alto impacto que resolver.

Paso 2: Diagnostica con DevTools
Una vez que el RUM ha identificado las páginas problemáticas, usa el panel Performance de Chrome DevTools para encontrar la causa. Nuestra guía Diagnostica el LCP con el panel Performance de Chrome DevTools cubre la configuración de throttling y el flujo de grabación paso a paso. Específicamente para el retraso de renderizado:

  1. Graba una carga de página con el botón "Record and reload".
  2. Abre la información "LCP breakdown" en la barra lateral Insights y anota el valor para Element render delay.
  3. Ahora examina la pista Main en la línea de tiempo. Busca long tasks (bloques amarillos con esquinas rojas) que ocurren entre el final de la solicitud de red del recurso del LCP y el marcador de tiempo del LCP. Estas tareas son la causa directa de tu retraso. Pasa el cursor sobre ellas para identificar los scripts responsables.

Causas comunes y soluciones de alto impacto

Un Element Render Delay alto casi siempre es causado por un main thread bloqueado.

Causa: CSS render blocking

El problema: Por defecto, el CSS es render blocking. El navegador no pintará ningún píxel hasta que haya descargado y analizado todos los archivos CSS enlazados en el <head>. Una hoja de estilos grande y compleja puede ocupar el main thread durante cientos de milisegundos. Esto retrasa el inicio de las etapas de layout y paint. Esto se agrava cuando los sitios cargan múltiples hojas de estilo, cada una requiere una solicitud de red y un ciclo de análisis separados. Para estrategias detalladas sobre cómo reducir el payload de CSS, lee nuestra guía sobre eliminar el CSS no utilizado.

La solución: Haz que tu CSS sea pequeño, limpio y cacheable.

  • Elimina el CSS no utilizado: Esta es la optimización de mayor impacto. En sitios grandes, el CSS no utilizado puede representar el 70% o más del tamaño total de la hoja de estilos. Herramientas como PurgeCSS pueden escanear tu HTML y JavaScript para identificar selectores sin usar. Eliminar reglas muertas reduce tanto el tiempo de descarga como el tiempo de análisis en el main thread.
  • Apunta a hojas de estilo pequeñas y cacheables: El tamaño ideal para un archivo CSS es de 10 a 15 kB (comprimido). Si es más pequeño, corres el riesgo de dividirlo en demasiadas solicitudes paralelas. Cada una tiene su propio gasto de conexión. Si es más grande, el tiempo de bloqueo crece, especialmente en redes móviles lentas. Una sola hoja de estilos bien estructurada en ese rango se descarga rápido, se analiza rápido y el navegador la cachea para visitas recurrentes.
  • Incrusta el CSS solo como último recurso: Incrustar el CSS crítico en un bloque <style> elimina la solicitud de red de la primera carga. Pero esto tiene un coste: el navegador no puede cachear el CSS incrustado. Cada visitante recurrente lo vuelve a descargar en cada página. Para la mayoría de los sitios con usuarios recurrentes, una hoja de estilos pequeña y externa que el navegador pueda cachear es la mejor opción. Incrustar el CSS solo tiene sentido para landing pages con muy pocos visitantes recurrentes.

Cómo cuantificar el impacto del CSS: Para medir cuánto contribuye tu CSS al retraso de renderizado, abre la pestaña Coverage en Chrome DevTools (Ctrl+Shift+P y escribe "Coverage"). Carga la página y observa el porcentaje de bytes no utilizados en tus archivos CSS. Un alto porcentaje de CSS no utilizado es una señal clara de que la limpieza reducirá el Element Render Delay.

Causa: Long tasks de JavaScript

El problema: Esta es la causa más común. La ejecución pesada de JavaScript, ya sea de frameworks, scripts analíticos, herramientas de A/B testing o código mal optimizado, puede monopolizar el main thread. Un solo long task puede bloquear el renderizado durante cientos de milisegundos. Esto se suma directamente al Element Render Delay. Google define un long task como cualquier tarea que tarda más de 50 ms, y las tareas que superan los 200 ms se consideran críticamente largas. Para ver una colección completa de estrategias de aplazamiento de JavaScript, lee nuestro artículo sobre 14 métodos para aplazar JavaScript.

La solución: Divide el trabajo.

  • Haz yield al main thread: Los long tasks deben dividirse en fragmentos más pequeños. Logras esto devolviendo el control al navegador (haciendo yield) periódicamente mediante setTimeout(..., 0) o la API más reciente scheduler.yield(). Esto permite al navegador realizar actualizaciones de renderizado entre tareas.
  • Optimiza y aplaza a terceros: Audita cada script de terceros. Si no son esenciales para el renderizado inicial, cárgalos con el atributo defer o inyéctalos después de que cargue la página. Los scripts de A/B testing son muy problemáticos porque suelen ser render blocking por diseño.
  • Usa requestAnimationFrame para actualizaciones visuales: Si el JavaScript debe manipular el DOM durante la carga de la página, envuelve el trabajo en requestAnimationFrame. Esto programa el trabajo justo antes del próximo paint. Asegura que el navegador tenga la oportunidad de renderizar fotogramas entre las operaciones de JavaScript.

Cómo identificar long tasks en DevTools

En el panel Performance de Chrome DevTools, los long tasks aparecen como bloques amarillos con un triángulo rojo en la esquina superior derecha de la pista "Main". Para identificar qué scripts son responsables:

  1. Graba una carga de página en el panel Performance.
  2. Localiza el marcador del LCP en la pista Timings.
  3. Examina la pista Main en busca de long tasks que ocurran entre la finalización de la solicitud de red del recurso del LCP y el marcador del LCP.
  4. Haz clic en estas tareas para ver el call stack en el panel Summary. El call stack revelará el archivo fuente y la función responsable del long task.

Terceros problemáticos comunes

Según mi experiencia de consultoría en el mundo real, los scripts de terceros más comunes que causan Element Render Delay incluyen:

  • Herramientas de A/B testing (Optimizely, VWO, AB Tasty): A menudo bloquean el renderizado a propósito para evitar parpadeos de contenido entre variantes. Mover la decisión del experimento al servidor (server-side testing) elimina este problema por completo.
  • Tag managers con etiquetas síncronas: Un tag manager configurado con etiquetas síncronas (no asíncronas) puede inyectar scripts render blocking. Audita tu contenedor para asegurar que todas las etiquetas se disparen después de que el DOM esté listo o que cargue la ventana.
  • Plataformas de gestión de consentimiento: Los banners de cookies que bloquean el renderizado hasta tomar una decisión pueden retrasar el LCP. Usa una implementación asíncrona que no bloquee el critical rendering path.
  • Widgets de chat: Los scripts de chat en vivo suelen ejecutar código de inicialización pesado al cargar la página. Aplaza su carga hasta que la página sea interactiva, o cárgalos al interactuar el usuario (por ejemplo, con un clic).

Causa: Client-Side Rendering (CSR)

El problema: Con el renderizado puro en el cliente, el elemento del LCP a menudo no existe en el HTML inicial. El JavaScript debe ejecutarse primero para construir el DOM e insertar el elemento del LCP. Solo entonces el navegador puede finalmente renderizarlo. Todo este proceso es un gran retraso de renderizado.

La solución: Renderiza en el servidor. No hay otra forma. Usa Server-Side Rendering (SSR) o Static Site Generation (SSG) para asegurar que el elemento del LCP esté presente en el documento HTML inicial enviado desde el servidor. Esto elimina toda la fase de renderizado impulsada por JavaScript como fuente de retraso.

Causa: Contenido oculto por otro código

El problema: A veces el elemento del LCP está en el DOM pero está oculto por CSS (por ejemplo, opacity: 0) o por un script, como una animación de "revelar al hacer scroll" o una herramienta de A/B testing que aún decide qué variante mostrar. El elemento está descargado y listo, pero no se puede pintar porque aún no es visible.

La solución: Asegura una visibilidad inmediata. Para el elemento del LCP, no uses animaciones de entrada ni ninguna lógica que lo oculte en la carga inicial. El elemento debe ser visible en el DOM y tener estilos para ser visible desde el primer paint. Configura las herramientas de A/B testing para que se ejecuten asíncronamente o asegúrate de que tengan un impacto mínimo en la visibilidad del elemento del LCP.

Causa: Tamaño excesivo del DOM

El problema: Un DOM grande (más de 1.500 nodos) aumenta el coste de cada operación de renderizado. Cada cálculo de layout, recálculo de estilos y operación de paint debe procesar más nodos, lo que requiere más tiempo en el main thread. Incluso si tu CSS y JavaScript están bien optimizados, un DOM inflado añade retraso de renderizado por puro volumen. Para leer estrategias detalladas de reducción del tamaño del DOM, consulta nuestra guía sobre evitar un tamaño excesivo del DOM.

La solución: Reduce el número de nodos DOM que participan en el renderizado inicial.

  • Simplifica la estructura HTML: Elimina elementos contenedores innecesarios. Aplana estructuras muy anidadas. Usa CSS Grid o Flexbox en lugar de usar elementos <div> extra para el diseño.
  • Virtualiza listas largas: Para páginas con cientos de elementos (cuadrículas de productos, tablas de datos), usa bibliotecas de virtualización que solo rendericen los elementos visibles actualmente en el viewport.
  • Renderiza de forma diferida el contenido debajo del pliegue: Usa content-visibility: auto (explicado más abajo) para omitir por completo el renderizado de secciones fuera de pantalla.

Tácticas avanzadas: Toma el control total del renderizado

Las aplicaciones complejas necesitan más control sobre el main thread.

Desbloquea el rendimiento con content-visibility

La propiedad CSS content-visibility se creó para páginas grandes. Al aplicar content-visibility: auto; en las secciones de tu página debajo del pliegue, le indicas al navegador que puede saltarse el trabajo de layout, paint y composite para ese contenido hasta que esté a punto de entrar al viewport. Esto reduce la carga de renderizado inicial y libera el main thread para pintar el elemento del LCP antes.

La clave es combinar content-visibility: auto con contain-intrinsic-size, que proporciona un tamaño estimado para el contenido oculto. Sin esto, el comportamiento de la barra de desplazamiento se vuelve errático porque el navegador no sabe qué tan altas son las secciones ocultas.

/* Aplícalo a secciones debajo del pliegue */
.below-fold-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px; /* Altura estimada de la sección */
}

/* Ejemplo: Una página de artículo largo */
.article-comments {
  content-visibility: auto;
  contain-intrinsic-size: auto 800px;
}

.related-products {
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}

.site-footer {
  content-visibility: auto;
  contain-intrinsic-size: auto 300px;
}

Impacto en el rendimiento: Según una publicación de Chrome Developers, aplicar content-visibility: auto a secciones debajo del pliegue de una página de blog redujo el tiempo de renderizado hasta 7 veces. El navegador omite por completo el trabajo de layout, paint y composite para estas secciones. Esto libera el main thread para centrarse en el contenido por encima del pliegue, incluido el elemento del LCP. El soporte en navegadores cubre todos los modernos: Chromium, Firefox y Safari 18+.

Descarga trabajo con Web Workers

Los Web Workers te permiten ejecutar JavaScript en un hilo en segundo plano, completamente fuera del main thread. Cualquier cálculo pesado en un Worker no puede bloquear el renderizado. Este sitio, corewebvitals.io, usa un Web Worker para procesar su analítica. El beneficio de rendimiento es real: el main thread permanece libre para pintar sin interrupciones.

Dicho esto, los Web Workers no son un patrón común en la mayoría de sitios web. Requieren un archivo JavaScript separado, comunicación por postMessage y no tienen acceso al DOM. La mayoría de las plataformas CMS y los creadores de sitios no ofrecen soporte integrado, lo que dificulta su implementación sin un desarrollo a medida. Si tienes la capacidad técnica para usarlos, son una de las formas más eficaces de despejar el main thread. Pero para la mayoría de equipos, las otras optimizaciones de esta página tendrán un impacto práctico mayor.

// main.js: Crea un worker y envía datos a procesar
const worker = new Worker('/js/analytics-worker.js');

// Descarga el procesamiento analítico pesado al hilo del worker
worker.postMessage({
  type: 'process-events',
  events: collectedEvents
});

// Recibe resultados sin bloquear el main thread
worker.onmessage = (event) => {
  console.log('Analítica procesada:', event.data.summary);
};

// analytics-worker.js: Se ejecuta en un hilo en segundo plano
self.onmessage = (event) => {
  if (event.data.type === 'process-events') {
    // El cálculo pesado ocurre aquí, fuera del main thread
    const summary = processEvents(event.data.events);
    self.postMessage({ summary });
  }
};

Impacto en el mundo real

  • Caso 1: El cuello de botella del CSS render blocking: DebugBear analizó un sitio donde un archivo CSS grande creaba un retraso de renderizado notable. La imagen del LCP se había descargado, pero el navegador estaba atascado analizando el CSS. Al incrustar simplemente el CSS crítico, el navegador pudo pintar el contenido de la página, incluido el elemento del LCP, casi de inmediato tras analizar el HTML. Esto eliminó de forma efectiva el retraso de renderizado causado por la hoja de estilos.
  • Caso 2: La penalización del A/B testing: Un importante sitio e-commerce descubrió que su LCP era frenado por un script de A/B testing síncrono. Aunque la imagen del LCP se descargó rápido, el script bloqueó el main thread mientras determinaba qué imagen de producto mostrar. Mover el test A/B para que se ejecutara tras la carga inicial de la página para los elementos no críticos mejoró al instante su LCP en más de 400 ms. Todo ese tiempo se recuperó del Element Render Delay.

Checklist: Cómo eliminar el Element Render Delay

Un Element Render Delay alto indica un main thread congestionado. Las soluciones implican despejar esa congestión para que el navegador pueda pintar.

  1. Valida con RUM: Usa datos de usuarios reales para confirmar que el Element Render Delay es el principal cuello de botella de tu LCP antes de optimizar.
  2. Elimina el CSS no utilizado: Audita y elimina las reglas CSS que nunca se aplican. Esta es la optimización CSS de mayor impacto. Usa herramientas como PurgeCSS o la pestaña Coverage en DevTools.
  3. Mantén hojas de estilo pequeñas y cacheables: Apunta a unos 10-15 kB (comprimidos) por archivo CSS. Suficientemente pequeño para descargar rápido, suficientemente grande para evitar un exceso de solicitudes paralelas. Deja que el navegador las cachee para visitantes recurrentes.
  4. Divide los long tasks de JavaScript: Ningún script debería ejecutarse más de 50 ms. Haz yield al main thread para permitir actualizaciones de renderizado.
  5. Audita y aplaza scripts de terceros: Pregúntate: ¿cada script de terceros justifica su lugar en la página? Aplaza todo lo que no sea esencial para el paint inicial.
  6. Usa SSR o SSG: No dependas del JavaScript en el cliente para renderizar el elemento del LCP. Envía el HTML completamente formado desde el servidor.
  7. Asegura la visibilidad inmediata del LCP: Elimina cualquier animación, script o estilo que oculte el elemento del LCP al cargar la página.
  8. Usa content-visibility: auto: En páginas largas, dile al navegador que omita el renderizado del contenido fuera de pantalla para liberar el main thread para el pintado por encima del pliegue.
  9. Reduce el tamaño del DOM: Aplana el HTML muy anidado, elimina contenedores innecesarios y virtualiza listas largas para reducir el coste de las operaciones de layout y paint.

Siguientes pasos: Sigue optimizando el LCP

El Element Render Delay es la fase final. Para abarcar las cuatro, continúa con:

  • Soluciona e identifica problemas del LCP: La metodología de diagnóstico completa para encontrar y solucionar todos los problemas del LCP usando field data y herramientas de laboratorio.
  • Optimiza la imagen del LCP: Selección de formatos de imagen, imágenes responsivas, precarga y errores comunes al optimizar imágenes.
  • Resource Load Delay: Asegura que el navegador descubra el recurso del LCP lo antes posible. Este suele ser el mayor cuello de botella individual del LCP.
  • Resource Load Duration: Reduce el tiempo de descarga mediante compresión, formatos modernos, configuración de CDN y optimización de red.

Escribo código, no informes.

Entro en tu equipo uno o dos sprints. Dejo montado el monitoring para que las métricas sigan verdes cuando me vaya.

Escríbeme
Optimiza el retraso de renderizado del elemento LCP Core Web Vitals Optimiza el retraso de renderizado del elemento LCP