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 necesariamente se corresponden con lo que el usuario ve en la pantalla. Además, las métricas de rendimiento más nuevas y centradas en el usuario, como First Contentful Paint (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 la primera pintura significativa (FMP) y el Índice de velocidad (SI) (ambos 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 todavía no identifican cuándo se cargó el contenido principal de la página.
A partir de los debates que se realizaron en el Grupo de trabajo sobre el rendimiento web del 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 determinar cuándo se renderiza el elemento más grande.
¿Qué es LCP?
El LCP informa el tiempo de renderización de la imagen, el bloque de texto o el video más grandes visibles en el viewport, en relación con la primera vez que el usuario navegó a la página.
¿Qué es una buena puntuación de LCP?
Para proporcionar una buena experiencia del usuario, los sitios deben esforzarse por tener el Procesamiento de imagen con contenido más grande 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 en dispositivos móviles y computadoras de escritorio.
¿Qué elementos se consideran?
Como se especifica actualmente en el apartado Largest Contentful Paint en la API, los tipos de elementos consideradas para Largest Contentful Paint son:
- Elementos
<img>
(el tiempo de presentación del primer fotograma se usa para contenido animado, como GIFs o PNG animados) - Elementos
<image>
dentro de un elemento<svg>
- Elementos
<video>
(se usa el tiempo de carga de la imagen de póster o el tiempo de presentación del primer cuadro de los videos, lo que ocurra primero) - Un elemento con una imagen de fondo cargada con la función
url()
(en lugar de un gradiente de CSS) - Elementos de nivel de bloque que contienen nodos de texto o algún otro elemento secundario de texto de nivel intercalado.
Ten en cuenta que la restricción de los elementos a este conjunto limitado fue intencional para mantener las cosas simples al principio. Es posible que se agreguen elementos adicionales (como el respaldo completo de <svg>
) 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 ver como "sin contenido". En los navegadores basados en Chromium, se incluyen los siguientes:
- Elementos con una opacidad 0, que son invisibles para el usuario
- Elementos que cubren todo el viewport y que probablemente se consideren como fondo y no como contenido
- Imágenes de marcador de posición u otras imágenes con baja entropía, que probablemente no reflejan el verdadero contenido de la página
Es probable que los navegadores sigan mejorando estas heurísticas para garantizar que podamos cumplir con las expectativas de los usuarios sobre cuál es el elemento con contenido más grande.
Estos videos "contentos" Es posible que las heurísticas difieran de las que se usan en First Contentful Paint (FCP), que puede considerar algunos de estos elementos, como imágenes de marcador de posición o imágenes de viewport completo, incluso si no son aptos para ser candidatos de LCP. A pesar de que ambos usan en su nombre, el objetivo de estas métricas es diferente. FCP mide cuando cualquier contenido se pinta en la pantalla y el LCP cuando se pinta el contenido principal para que el LCP sea más selectivo.
¿Cómo se determina el tamaño de un elemento?
El tamaño del elemento informado para el LCP suele ser el tamaño que es visible para el usuario dentro del viewport. Si el elemento se extiende fuera del viewport, o si alguno de ellos está recortado o tiene un desbordamiento no visible, esas partes no cuentan para el tamaño del elemento.
En el caso de los elementos de imagen cuyo tamaño intrínseco se cambió, el tamaño que se informa es el visible o el intrínseco, el que sea más pequeño.
Para 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, el LCP no tiene en cuenta los márgenes, el relleno ni los bordes aplicados con CSS.
¿Cuándo se informa el LCP?
Las páginas web a menudo se cargan en etapas y, como resultado, es posible que el elemento más grande de la página cambie.
Para controlar este posible cambio, el navegador envía un PerformanceEntry
de tipo largest-contentful-paint
que identifica el elemento con contenido más grande en cuanto el navegador pintó el primer fotograma. Sin embargo, después de renderizar los fotogramas posteriores, enviará otro PerformanceEntry
cada vez que cambie el elemento con contenido más grande.
Por ejemplo, en una página con texto y una imagen hero, al principio el navegador podría renderizar el texto. En ese momento, el navegador enviará una entrada largest-contentful-paint
cuya propiedad element
probablemente haría referencia a un <p>
o <h1>
. Más adelante, una vez que la imagen hero termine de cargarse, se enviará una segunda entrada largest-contentful-paint
y su propiedad element
hará referencia a <img>
.
Un elemento solo se puede considerar como el elemento con contenido más grande después de que se renderiza y es visible para el usuario. Las imágenes que todavía no se cargan no se consideran "renderizadas". Tampoco los nodos de texto 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 se creará otro PerformanceEntry
apenas termine de renderizarse el elemento más grande.
Además de la carga tardía de imágenes y fuentes, una página puede agregar nuevos elementos al DOM a medida que haya nuevo contenido 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 PerformanceEntry
nuevo.
Si se quita el elemento con contenido más grande 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 dejará de informar entradas nuevas tan pronto como el usuario interactúe con la página (mediante un toque, un desplazamiento o la presión de una 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 último envío de PerformanceEntry
a tu servicio de estadísticas.
Tiempo de carga y 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 (debido a que ya se expone a través de muchas otras APIs web).
Esto puede llevar a la situación aparentemente imposible en la que las APIs web informan el LCP como antes que FCP. Este no es el caso, pero solo aparece así debido a esta restricción de seguridad.
Siempre que sea posible, se recomienda establecer el encabezado Timing-Allow-Origin
para que las 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 el envío de nuevas entradas de rendimiento, los cambios en el tamaño o la posición de un elemento no generan nuevos candidatos de LCP. Solo se consideran 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 inicialmente se renderizan fuera de la pantalla y, luego, pasan a la pantalla. También significa que los elementos renderizados inicialmente en el viewport que luego se desplazan hacia abajo, fuera de la vista aún informarán su tamaño inicial en el viewport.
Ejemplos
Estos son algunos ejemplos de cuándo se produce el Procesamiento de imagen con contenido más grande en algunos sitios web populares:
En los dos cronogramas anteriores, los elementos más grandes cambian a medida que se carga el contenido. En el primer ejemplo, se agrega contenido nuevo al DOM y eso cambia qué elemento es el más grande. En el segundo ejemplo, se cambia el diseño y se quita del viewport el contenido que antes era el más grande.
Si bien suele suceder que el contenido de carga tardía es más grande que el contenido que ya está en la página, ese no es necesariamente el caso. En los siguientes dos ejemplos, se muestra que el LCP ocurre antes de que la página se cargue por completo.
En el primer ejemplo, el logotipo de Instagram se carga relativamente antes y sigue siendo el elemento más grande, incluso cuando el resto del contenido se muestra de manera progresiva. 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 todas las imágenes individuales son más pequeñas que este párrafo, 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 lab o en el campo y está disponible en las siguientes herramientas:
Herramientas de campo
- Informe sobre la experiencia del usuario en Chrome
- PageSpeed Insights
- Search Console (informe de Métricas web esenciales)
- Biblioteca JavaScript
web-vitals
Herramientas del 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 actual de LCP. En general, el valor startTime
de la última entrada emitida es el valor de LCP, pero no siempre es así. No todas las entradas de largest-contentful-paint
son válidas para medir el LCP.
En la siguiente sección, se indican 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 de
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 continuará enviando entradas de
largest-contentful-paint
después de que una página haya estado en 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 las entradas de
largest-contentful-paint
cuando la página se restablece desde la memoria caché atrás/adelante, pero el LCP debe medirse en estos casos, ya que los usuarios las experimentan como visitas distintas a la página. - La API no tiene en cuenta los elementos de los iframes, pero la métrica sí, ya que 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), se mostrará una diferencia entre CrUX y RUM. Para medir el LCP correctamente, debes tenerlos en cuenta. Los submarcos pueden usar la API a fin de 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 el LCP, que se encarga de estas diferencias por ti (cuando es posible, ten en cuenta que el problema del iframe no se aborda):
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é 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 es el mismo que el más grande, y los desarrolladores pueden estar 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 para optimizar el LCP que te guiará en el proceso de identificar los tiempos de LCP en el campo y usar los datos de los labs para desglosarlos y optimizarlos.
Recursos adicionales
- Lecciones aprendidas de la supervisión de rendimiento en Chrome de Annie Sullivan en performance.now() (2019)
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, es necesario realizar cambios a veces, y estos pueden aparecer como mejoras o regresiones en tus informes y paneles internos.
Para ayudarte a administrar esto, todos los cambios que realices 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 al grupo de Google web-vitals-feedback.