Largest Contentful Paint (LCP)

Navegadores compatibles

  • 77
  • 79
  • 122
  • x

Origen

Largest Contentful Paint (LCP) es una métrica estable de Métricas web esenciales para medir la velocidad de carga percibida. Marca el punto en el cronograma de carga de la página en el que es probable que se haya cargado el contenido principal de la página. Un LCP rápido ayuda a asegurarle al usuario que la página es útil.

Históricamente, ha sido un desafío para los desarrolladores web medir la rapidez con la que el contenido principal de una página web se carga y es visible para los usuarios. Las métricas más antiguas, como load o DOMContentLoaded, no funcionan bien porque no necesariamente se corresponden con lo que el usuario ve en la pantalla. Además, las métricas de rendimiento más recientes y centradas en el usuario, como el primer procesamiento de imagen con contenido (FCP), solo capturan el inicio 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 Primera pintura significativa (FMP) y Índice de velocidad (SI) (ambas disponibles en Lighthouse) para ayudar a capturar más de la experiencia de carga después de la pintura inicial. Sin embargo, estas métricas son complejas, difíciles de explicar y a menudo incorrectas, lo que significa que aún no identifican cuándo se carga el contenido principal de la página.

A partir de los debates que se hicieron en el Grupo de trabajo de rendimiento web de W3C y las investigaciones realizadas 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 o el bloque de texto más grande visible en el viewport, en relación con el momento en que el usuario navegó a la página por primera vez.

¿Qué es una buena puntuación de LCP?

Para proporcionar una buena experiencia del usuario, los sitios deben esforzarse por tener un LCP 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 dispositivos móviles y de escritorio.

Los valores de LCP correctos son de 2.5 segundos o menos, los valores malos son mayores a 4.0 segundos y cualquier otro valor debe mejorarse
Un buen valor de LCP es de 2.5 segundos o menos.

¿Qué elementos se consideran?

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

La restricción de los elementos a este conjunto limitado fue intencional para reducir la complejidad. Es posible que se agreguen elementos adicionales (como la compatibilidad completa 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 los usuarios podrían considerar "sin contenido". En el caso de los navegadores basados en Chromium, estos son los siguientes:

  • Elementos con una opacidad de 0, que los hace invisibles para el usuario
  • Elementos que cubren todo el viewport, que probablemente sean elementos en segundo plano.
  • Imágenes de marcadores de posición, o bien otras imágenes con baja entropía, que probablemente no reflejen el verdadero contenido de la página

Es probable que los navegadores sigan mejorando esta heurística para garantizar que cumplan con las expectativas del usuario respecto de cuál es el elemento contentful más grande.

Estas heurísticas con "contenido" difieren de las que usa FCP, que podría considerar algunos de estos elementos, como imágenes de marcador de posición o imágenes de viewport completo, incluso si no son aptas para ser candidatas para LCP. A pesar de que ambas usan "contentful" en el nombre, el objetivo de estas métricas es diferente. El FCP mide cuándo se pinta cualquier contenido en la pantalla, mientras que el LCP mide cuándo se pinta el contenido principal.

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

El tamaño del elemento informado para LCP suele ser el tamaño visible para el usuario dentro del viewport. Si el elemento se extiende fuera del viewport, o si alguno de ellos se recorta o tiene un overflow no visible, esas partes no se consideran en 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, el que sea más pequeño.

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

Para todos los elementos, LCP no tiene en cuenta los márgenes, los paddings ni los bordes aplicados con CSS.

¿Cuándo se informa el LCP?

Las páginas web suelen cargarse en etapas y, como resultado, el elemento más grande de la página puede cambiar durante la carga.

Para controlar este potencial de cambio, el navegador envía un PerformanceEntry de tipo largest-contentful-paint que identifica el elemento con contenido más grande tan pronto como el navegador pinta el primer fotograma. Después de renderizar los fotogramas posteriores, envía otro PerformanceEntry cada vez que cambia el elemento con contenido más grande.

Por ejemplo, en una página con texto y una imagen hero, es posible que al principio el navegador renderice solo el texto, y que envíe una entrada largest-contentful-paint cuya propiedad element haga referencia a <p> o <h1>. Una vez que la imagen principal termina de cargarse, se envía una segunda entrada largest-contentful-paint, con una propiedad element que hace referencia a <img>.

Un elemento solo se puede considerar el elemento con contenido más grande 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 los nodos de texto que usan fuentes web durante el período de bloqueo de fuentes. En esos casos, un elemento más pequeño podría informarse como el elemento con contenido más grande, pero apenas se termina de renderizar el elemento más grande, se crea otro PerformanceEntry.

Además de las imágenes y fuentes de carga tardía, una página puede agregar elementos nuevos al DOM a medida que hay nuevo contenido disponible. Si alguno de estos elementos nuevos es más grande que el elemento con contenido más grande anterior, se crea un PerformanceEntry nuevo.

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

El navegador deja de informar entradas nuevas en cuanto el usuario interactúa con la página (mediante un toque, un desplazamiento o una tecla), porque la interacción del usuario a menudo cambia lo que es visible para el usuario (especialmente cuando se desplaza).

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

Tiempo de carga en comparación con 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 su lugar, solo está disponible su tiempo de carga, que otras APIs ya exponen.

Esto puede llevar a la situación aparentemente imposible en la que las APIs web informan el LCP como antes que FCP. Esto se debe solo a esta restricción de seguridad y no representa lo que está sucediendo.

Siempre que sea posible, te recomendamos que configures 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 de calcular y despachar entradas de rendimiento nuevas, los cambios en el tamaño o la posición de un elemento no generan candidatos nuevos para LCP. Solo se consideran el tamaño inicial y la posición del elemento en el viewport.

Esto significa que es posible que no se informen las imágenes que inicialmente se renderizan fuera de la pantalla y, luego, pasan a hacerlo. También significa que los elementos renderizados inicialmente en el viewport, que luego se quitan de la vista aún informan su tamaño inicial en el viewport.

Ejemplos

Estos son algunos ejemplos de cuándo se produce Largest Contentful Paint en algunos sitios web populares:

Mayor cronograma de procesamiento de imagen con contenido de cnn.com
Un cronograma de LCP de cnn.com.
Cronograma de Contentful Paint más grande de techcrunch.com
Un cronograma de LCP de techcrunch.com.

En ambos cronogramas, el elemento más grande (destacado en verde) cambia a medida que se carga el contenido. En el primer ejemplo, se agrega contenido nuevo al DOM y se cambia el elemento de mayor tamaño. En el segundo ejemplo, cambia el diseño y quita un elemento de contenido anterior más grande del viewport.

Si bien el contenido de carga tardía suele ser más grande que el que ya se encuentra en la página, no es necesariamente el caso. En los siguientes dos ejemplos, se muestra el LCP que ocurre antes de que la página se cargue por completo.

Cronograma de Contentful Paint más grande de instagram.com
Un cronograma de LCP de instagram.com.
Cronograma de Contentful Paint más grande de google.com
Un cronograma de LCP de google.com.

En el primer ejemplo, el logotipo de Instagram se carga relativamente antes y sigue siendo el elemento más grande, incluso cuando se agrega 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 las imágenes o el logotipo terminen de cargarse. Debido a que cada imagen individual es más pequeña que este párrafo, sigue siendo el elemento más grande en todo el proceso de carga.

Cómo medir el LCP

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

Herramientas de campo

Herramientas del lab

Mide el LCP en JavaScript

Para medir el LCP en JavaScript, usa la API de Largest Contentful Paint. En el siguiente ejemplo, se muestra cómo crear un PerformanceObserver que escuche 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 de largest-contentful-paint registrada 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 todas las entradas largest-contentful-paint son válidas para medir el 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 envía 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 continúa despachando entradas largest-contentful-paint después de que una página pasa a segundo plano, pero esas entradas se deben ignorar cuando se calcula el LCP. Solo se pueden considerar los elementos si la página estuvo en primer plano todo el tiempo.
  • La API no informa entradas largest-contentful-paint cuando la página se restablece desde la memoria caché atrás/adelante, pero el LCP se debe medir en estos casos, ya que los usuarios las experimentan como visitas distintas a la página.
  • La API no tiene en cuenta los elementos dentro de iframes, pero la métrica sí porque forman parte de la experiencia del usuario de 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 se mostrará como una diferencia entre CrUX y RUM. Para medir el LCP correctamente, debes incluir iframes. Los submarcos pueden usar la API para informar sus entradas largest-contentful-paint al marco superior para la agregación.
  • La API mide el LCP desde el inicio de la navegación. En el caso de las páginas renderizadas previamente, mide el LCP desde activationStart, ya que corresponde al tiempo de LCP que experimenta el usuario.

En lugar de memorizar todas estas diferencias sutiles, recomendamos que los desarrolladores usen la biblioteca de JavaScript web-vitals para medir el LCP, que controla la mayoría de estas diferencias por ti. (No trata 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 obtener un ejemplo completo de cómo medir el LCP en JavaScript.

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

En algunos casos, el elemento (o elementos) más importante de la página no es el mismo que el más grande, y es posible que los desarrolladores estén más interesados en medir los tiempos de renderización de esos 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 una guía completa disponible sobre la optimización del LCP que te guiará por el proceso de identificación de los tiempos de LCP en el campo y el uso de los datos del lab para desglosar y optimizar.

Recursos adicionales

Registro de cambios

Ocasionalmente, se detectan errores en las APIs que se usan para medir métricas y, a veces, en las definiciones de las métricas en sí. Como resultado, a veces se deben realizar cambios, que 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 muestran en este registro de cambios.

Si tienes comentarios sobre estas métricas, envíalos en el grupo de Google web-vitals-feedback.