Largest Contentful Paint (LCP)

Navegadores compatibles

  • Chrome: 77.
  • Edge: 79.
  • Firefox: 122.
  • Safari: No se admite.

Origen

Históricamente, ha sido un desafío para los desarrolladores web medir la rapidez con la que se carga el contenido principal de una página web y es visible para los usuarios. Las métricas más antiguas, como load o DOMContentLoaded, no funcionan bien porque no se corresponden necesariamente con lo que el usuario ve en su pantalla. Además, las métricas de rendimiento más recientes centradas en el usuario, como el primer procesamiento de imagen con contenido (FCP), solo capturan el comienzo de la experiencia de carga. Si una página muestra una pantalla de presentación o un indicador de carga, este momento no es muy relevante para el usuario.

En el pasado, recomendamos métricas de rendimiento como el primer procesamiento de imagen significativo (FMP) y el índice de velocidad (SI) (ambos disponibles en Lighthouse) para ayudar a capturar más de la experiencia de carga después del procesamiento de imagen inicial, pero estas métricas son complejas, difíciles de explicar y, a menudo, incorrectas, lo que significa que aún no identifican cuándo se cargó el contenido principal de la página.

En función de las discusiones en el grupo de trabajo de rendimiento web del W3C y de la investigación realizada en Google, descubrimos que una forma más precisa de medir cuándo se carga el contenido principal de una página es observar cuándo se renderiza el elemento más grande.

¿Qué es el LCP?

LCP informa el tiempo de renderización de la imagen, el bloque de texto o el video más grandes que se pueden ver en el viewport, en relación con el momento en que el usuario navegó a la página por primera vez.

¿Qué es un buen nivel de LCP?

Para proporcionar una buena experiencia del usuario, los sitios deben esforzarse por tener una Largest Contentful Paint de 2.5 segundos o menos. Para asegurarte de alcanzar este objetivo para la mayoría de los usuarios, un buen umbral para medir es el percentil 75 de las cargas de páginas, segmentadas entre los dispositivos móviles y las computadoras de escritorio.

Los valores buenos de LCP son de 2.5 segundos o menos, los valores deficientes son superiores a 4.0 segundos y los valores intermedios deben mejorarse.
Un buen valor de LCP es de 2.5 segundos o menos.

¿Qué elementos se tienen en cuenta?

Como se especifica actualmente en la API de Largest Contentful Paint, los tipos de elementos que se consideran para Largest Contentful Paint son los siguientes:

Ten en cuenta que restringir los elementos a este conjunto limitado fue intencional para mantener la simplicidad al principio. Es posible que se agreguen elementos adicionales (como la compatibilidad total con <svg>) en el futuro a medida que se realicen más investigaciones.

Además de considerar solo algunos elementos, las mediciones de LCP usan heurísticas para excluir ciertos elementos que es probable que los usuarios consideren "sin contenido". En el caso de los navegadores basados en Chromium, estos incluyen lo siguiente:

  • Elementos con una opacidad de 0 que son invisibles para el usuario
  • Elementos que cubren todo el viewport y que probablemente se consideren como fondo en lugar de contenido
  • Imágenes de marcador de posición o imágenes con baja entropía que probablemente no reflejen el contenido real de la página

Es probable que los navegadores sigan mejorando estas heurísticas para garantizar que coincidamos con las expectativas de los usuarios sobre cuál es el elemento con más contenido.

Estas heurísticas "con contenido" pueden diferir de las que usa el primer procesamiento de imagen con contenido (FCP), que puede considerar algunos de estos elementos, como las imágenes de marcadores de posición o las imágenes de viewport completas, incluso si no son aptos para ser candidatos de LCP. A pesar de que ambas incluyen la palabra "contenido" en su nombre, el objetivo de estas métricas es diferente. El FCP mide cuándo se pinta cualquier contenido en la pantalla y el LCP cuando se pinta el contenido principal, por lo que el LCP se diseñó para ser más selectivo.

¿Cómo se determina el tamaño de un elemento?

Por lo general, el tamaño del elemento informado para la LCP es el que el usuario puede ver dentro del viewport. Si el elemento se extiende fuera del viewport o si alguna parte está recortada o tiene un desbordamiento no visible, esas porciones no se tienen en cuenta para el tamaño del elemento.

En el caso de los elementos de imagen a los que se les cambió el tamaño desde su tamaño intrínseco, el tamaño que se informa es el visible o el intrínseco, lo que sea más pequeño.

En el caso de los elementos de texto, la LCP solo considera el rectángulo más pequeño que puede contener todos los nodos de texto.

Para todos los elementos, el LCP no considera los márgenes, los rellenos ni los bordes aplicados con CSS.

¿Cuándo se informa el LCP?

Las páginas web suelen cargarse en etapas y, como resultado, es posible que cambie el elemento más grande de la página.

Para controlar este potencial de cambio, el navegador envía un PerformanceEntry de tipo largest-contentful-paint que identifica el elemento de contenido más grande en cuanto el navegador pinta el primer fotograma. Sin embargo, después de renderizar los fotogramas posteriores, enviará otro PerformanceEntry cada vez que cambie el elemento de contenido más grande.

Por ejemplo, en una página con texto y una imagen hero, es posible que el navegador solo renderice el texto al principio, en cuyo caso enviaría una entrada largest-contentful-paint cuya propiedad element probablemente haga referencia a un <p> o <h1>. Más adelante, una vez que se termine de cargar la imagen hero, se enviará una segunda entrada largest-contentful-paint y su propiedad element hará referencia a <img>.

Un elemento solo se puede considerar el elemento con más contenido después de que se renderiza y es visible para el usuario. Las imágenes que aún no se cargaron no se consideran "renderizadas". Tampoco lo hacen los nodos de texto que usan fuentes web durante el período de bloqueo de fuentes. En esos casos, es posible que un elemento más pequeño se informe como el elemento con contenido más grande, pero en cuanto se termina de renderizar el elemento más grande, se crea otro PerformanceEntry.

Además de las imágenes y las fuentes que se cargan tarde, una página puede agregar elementos nuevos al DOM a medida que el contenido nuevo esté disponible. Si alguno de estos elementos nuevos es más grande que el elemento con contenido más grande anterior, también se informará un nuevo PerformanceEntry.

Si se quita el elemento con contenido más grande del viewport o incluso del DOM, seguirá siendo el elemento con contenido más grande, a menos que se renderice un elemento más grande.

El navegador dejará de informar entradas nuevas en cuanto el usuario interactúe con la página (a través de una presión, un desplazamiento o una pulsación de tecla), ya que la interacción del usuario suele cambiar lo que es visible para el usuario (lo que es especialmente cierto con el desplazamiento).

Para fines de análisis, solo debes informar el PerformanceEntry enviado más recientemente a tu servicio de estadísticas.

Tiempo de carga en comparación con el tiempo de renderización

Por motivos de seguridad, la marca de tiempo de renderización de las imágenes no se expone para las imágenes de origen cruzado que no tienen el encabezado Timing-Allow-Origin. En cambio, solo se expone su tiempo de carga (ya que este ya se expone a través de muchas otras APIs web).

Esto puede generar la situación aparentemente imposible en la que las APIs web informan que el LCP es anterior al FCP. No es el caso, pero solo aparece así debido a esta restricción de seguridad.

Siempre que sea posible, se recomienda configurar el encabezado Timing-Allow-Origin para que tus métricas sean más precisas.

¿Cómo se manejan los cambios de diseño y tamaño de los elementos?

Para mantener baja la sobrecarga de rendimiento del cálculo y envío de nuevas entradas de rendimiento, los cambios en el tamaño o la posición de un elemento no generan candidatos de LCP nuevos. Solo se considera el tamaño y la posición iniciales del elemento en el viewport.

Esto significa que es posible que no se informen las imágenes que se renderizan inicialmente fuera de la pantalla y, luego, se transfieren a la pantalla. También significa que los elementos renderizados inicialmente en el viewport que luego se desplazan hacia abajo y quedan fuera de la vista seguirán informando su tamaño inicial en el viewport.

Ejemplos

A continuación, se muestran algunos ejemplos de cuándo se produce Largest Contentful Paint en algunos sitios web populares:

Cronograma de Largest Contentful Paint de cnn.com
Un cronograma de LCP de cnn.com.
Línea de tiempo de Largest Contentful Paint de techcrunch.com
Un cronograma de LCP de techcrunch.com.

En ambos cronogramas anteriores, el elemento más grande cambia a medida que se carga el contenido. En el primer ejemplo, se agrega contenido nuevo al DOM, lo que cambia el elemento más grande. En el segundo ejemplo, el diseño cambia y el contenido que antes era el más grande se quita del viewport.

Si bien, a menudo, el contenido que se carga más tarde es más grande que el que ya está en la página, no siempre es así. En los siguientes dos ejemplos, se muestra que el LCP ocurre antes de que la página se cargue por completo.

Cronograma de Largest Contentful Paint de instagram.com
Un cronograma de LCP de instagram.com.
Cronograma de Largest Contentful Paint de google.com
Un cronograma de LCP de google.com.

En el primer ejemplo, el logotipo de Instagram se carga con bastante anticipación y sigue siendo el elemento más grande, incluso mientras se muestra progresivamente otro contenido. En el ejemplo de la página de resultados de la Búsqueda de Google, el elemento más grande es un párrafo de texto que se muestra antes de que se termine de cargar cualquiera de las imágenes o el logotipo. Dado que todas las imágenes individuales son más pequeñas que este párrafo, este sigue siendo el elemento más grande durante todo el proceso de carga.

Cómo medir el LCP

El LCP se puede medir en el laboratorio o en el campo, y está disponible en las siguientes herramientas:

Herramientas de campo

Herramientas de lab

Mide el LCP en JavaScript

Para medir el LCP en JavaScript, puedes usar la API de Largest Contentful Paint. En el siguiente ejemplo, se muestra cómo crear un PerformanceObserver que escuche las entradas de largest-contentful-paint y las registre en la consola.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('LCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'largest-contentful-paint', buffered: true});

En el ejemplo anterior, cada entrada registrada de largest-contentful-paint representa el candidato de LCP actual. En general, el valor de startTime de la última entrada emitida es el valor de LCP; sin embargo, no siempre es así. No todas las entradas de largest-contentful-paint son válidas para medir la LCP.

En la siguiente sección, se enumeran las diferencias entre lo que informa la API y cómo se calcula la métrica.

Diferencias entre la métrica y la API

  • La API enviará entradas largest-contentful-paint para las páginas cargadas en una pestaña en segundo plano, pero esas páginas se deben ignorar cuando se calcula el LCP.
  • La API seguirá enviando entradas largest-contentful-paint después de que una página se haya enviado a segundo plano, pero esas entradas se deben ignorar cuando se calcula el LCP (los elementos solo se pueden considerar si la página estuvo en primer plano todo el tiempo).
  • La API no informa entradas de largest-contentful-paint cuando la página se restablece desde la caché de atrás/adelante, pero se debe medir la LCP en estos casos, ya que los usuarios las experimentan como visitas a páginas distintas.
  • La API no considera los elementos dentro de los iframes, pero la métrica sí, ya que forman parte de la experiencia del usuario en la página. En las páginas con un LCP dentro de un iframe (por ejemplo, una imagen de póster en un video incorporado), esto aparecerá como una diferencia entre CrUX y RUM. Para medir correctamente el LCP, debes considerarlos. Los submarcos pueden usar la API para informar sus entradas de largest-contentful-paint al marco superior para la agregación.
  • La API mide el LCP desde el inicio de la navegación, pero para las páginas renderizadas previamente, el LCP se debe medir desde activationStart, ya que corresponde al tiempo de LCP que experimenta el usuario.

En lugar de memorizar todas estas diferencias sutiles, los desarrolladores pueden usar la biblioteca de JavaScript web-vitals para medir la LCP, que controla estas diferencias por ti (siempre que sea posible; ten en cuenta que no se aborda el problema del iframe):

import {onLCP} from 'web-vitals';

// Measure and log LCP as soon as it's available.
onLCP(console.log);

Consulta el código fuente de onLCP() para ver un ejemplo completo de cómo medir el LCP en JavaScript.

¿Qué sucede si el elemento más grande no es el más importante?

En algunos casos, el elemento (o los elementos) más importantes de la página no son los mismos que el elemento más grande, y es posible que a los desarrolladores les interese más medir los tiempos de renderización de estos otros elementos. Esto es posible con la API de Element Timing, como se describe en el artículo sobre métricas personalizadas.

Cómo mejorar el LCP

Hay disponible una guía completa sobre la optimización del LCP para guiarte en el proceso de identificación de los tiempos de LCP en el campo y usar los datos de lab para desglosarlos y optimizarlos.

Recursos adicionales

Registro de cambios

En ocasiones, se descubren errores en las APIs que se usan para medir las métricas y, a veces, en las definiciones de las métricas. Como resultado, a veces se deben realizar cambios, y estos pueden aparecer como mejoras o regresiones en tus informes y paneles internos.

Para ayudarte a administrar esto, todos los cambios en la implementación o definición de estas métricas se mostrarán en este registro de cambios.

Si tienes comentarios sobre estas métricas, puedes enviarlos en el grupo de Google web-vitals-feedback.