Largest Contentful Paint (LCP)

Navigateurs pris en charge

  • Chrome: 77.
  • Edge: 79.
  • Firefox: 122.
  • Safari: non compatible.

Source

Historiquement, il a été difficile pour les développeurs Web de mesurer la rapidité avec laquelle le contenu principal d'une page Web se charge et est visible par les utilisateurs. Les métriques plus anciennes telles que load ou DOMContentLoaded ne fonctionnent pas bien, car elles ne correspondent pas nécessairement à ce que l'utilisateur voit à l'écran. De plus, les métriques de performances plus récentes axées sur l'utilisateur, comme le FCP (First Contentful Paint), ne capturent que le tout début de l'expérience de chargement. Si une page affiche un écran de démarrage ou un indicateur de chargement, ce moment n'est pas très pertinent pour l'utilisateur.

Par le passé, nous recommandions des métriques de performances telles que First Meaningful Paint (FMP) (Première peinture significative) et Speed Index (SI) (Indice de vitesse) (les deux disponibles dans Lighthouse) pour mieux capturer l'expérience de chargement après la peinture initiale. Toutefois, ces métriques sont complexes, difficiles à expliquer et souvent incorrectes, ce qui signifie qu'elles n'identifient toujours pas quand le contenu principal de la page a été chargé.

D'après les discussions du groupe de travail sur les performances Web du W3C et les recherches menées par Google, nous avons constaté qu'il était plus précis de mesurer le moment où le contenu principal d'une page est chargé en examinant le moment où l'élément le plus volumineux est affiché.

Qu'est-ce que le LCP ?

Le LCP indique le délai d'affichage de la plus grande image, vidéo ou section de texte visible dans la fenêtre d'affichage, par rapport au moment où l'utilisateur a accédé à la page pour la première fois.

Qu'est-ce qu'un bon score LCP ?

Pour offrir une expérience utilisateur de qualité, les sites doivent s'efforcer de 2,5 secondes ou moins pour la valeur "Largest Contentful Paint". Pour vous assurer d'atteindre cet objectif pour la plupart de vos utilisateurs, nous vous recommandons de mesurer le 75e centile des chargements de pages, segmentés par appareil mobile et ordinateur.

Une valeur LCP satisfaisante est de 2,5 secondes ou moins. Une valeur LCP mauvaise est supérieure à 4 secondes. Une valeur LCP comprise entre ces deux valeurs doit être améliorée.
Une valeur LCP satisfaisante est de 2,5 secondes ou moins.

Quels éléments sont pris en compte ?

Comme indiqué actuellement dans l'API Largest Contentful Paint, les types d'éléments pris en compte pour Largest Contentful Paint sont les suivants:

  • Éléments <img> (la durée de présentation du premier frame est utilisée pour les contenus animés tels que les GIF ou les PNG animés)
  • Éléments <image> dans un élément <svg>
  • éléments <video> (le temps de chargement de l'image poster ou le temps de présentation du premier frame pour les vidéos est utilisé, le plus tôt possible)
  • Élément avec une image de fond chargée à l'aide de la fonction url() (par opposition à un dégradé CSS)
  • Éléments de niveau bloc contenant des nœuds de texte ou d'autres éléments enfants de texte au niveau de l'alignement en ligne.

Notez que nous avons volontairement limité les éléments à cet ensemble afin de simplifier les choses au début. D'autres éléments (comme la prise en charge complète de <svg>) pourront être ajoutés à l'avenir à mesure que des recherches supplémentaires seront menées.

En plus de ne prendre en compte que certains éléments, les mesures du LCP utilisent des heuristiques pour exclure certains éléments que les utilisateurs sont susceptibles de considérer comme "sans contenu". Pour les navigateurs Chromium, il s'agit des navigateurs suivants:

  • Éléments dont l'opacité est de 0, qui sont invisibles pour l'utilisateur
  • Éléments qui couvrent l'intégralité de la fenêtre d'affichage et qui sont probablement considérés comme un arrière-plan plutôt que comme un contenu
  • Images fictives ou autres images à faible entropie qui ne reflètent probablement pas le contenu réel de la page

Les navigateurs vont probablement continuer à améliorer ces heuristiques pour s'assurer que nous répondons aux attentes des utilisateurs concernant l'élément le plus pertinent.

Ces heuristiques "significatives" peuvent différer de celles utilisées par le First Contentful Paint (FCP), qui peut prendre en compte certains de ces éléments, tels que les images d'espace réservé ou les images de la fenêtre d'affichage complète, même s'ils ne peuvent pas être des candidats au LCP. Bien que ces métriques contiennent le mot "contenu" dans leur nom, leur objectif est différent. FCP mesure le moment où n'importe quel contenu est affiché à l'écran, et LCP le moment où le contenu principal est affiché. LCP est donc censé être plus sélectif.

Comment la taille d'un élément est-elle déterminée ?

La taille de l'élément indiquée pour le LCP correspond généralement à celle visible par l'utilisateur dans la fenêtre d'affichage. Si l'élément s'étend en dehors de la fenêtre d'affichage, ou si une partie de l'élément est rognée ou présente un dépassement non visible, ces parties ne sont pas prises en compte dans la taille de l'élément.

Pour les éléments d'image qui ont été redimensionnés à partir de leur taille intrinsèque, la taille indiquée est la taille visible ou la taille intrinsèque, la plus petite.

Pour les éléments textuels, la LCP ne prend en compte que le plus petit rectangle pouvant contenir tous les nœuds de texte.

Pour tous les éléments, le LCP ne prend pas en compte les marges, les marges intérieures ni les bordures appliquées à l'aide de CSS.

Quand le LCP est-il enregistré ?

Les pages Web se chargent souvent par étapes. Il est donc possible que l'élément le plus volumineux de la page change.

Pour gérer ce potentiel de modification, le navigateur distribue un PerformanceEntry de type largest-contentful-paint identifiant le plus grand élément de contenu dès que le navigateur a peint le premier frame. Toutefois, après le rendu des frames suivants, il distribue un autre PerformanceEntry chaque fois que l'élément le plus volumineux change.

Par exemple, sur une page contenant du texte et une image héros, le navigateur peut n'afficher initialement que le texte. À ce stade, il distribue une entrée largest-contentful-paint dont la propriété element fait probablement référence à un <p> ou à un <h1>. Plus tard, une fois l'image principale chargée, une deuxième entrée largest-contentful-paint sera envoyée et sa propriété element référencera <img>.

Un élément ne peut être considéré comme le plus grand élément avec contenu qu'après avoir été affiché et être visible par l'utilisateur. Les images qui n'ont pas encore été chargées ne sont pas considérées comme "rendues". Les nœuds de texte qui utilisent des polices Web ne sont pas non plus concernés pendant la période de blocage des polices. Dans ce cas, un élément plus petit peut être signalé comme étant le plus grand élément avec contenu, mais dès que l'élément plus grand a terminé le rendu, un autre PerformanceEntry est créé.

En plus des images et des polices chargées tardivement, une page peut ajouter de nouveaux éléments au DOM à mesure que de nouveaux contenus deviennent disponibles. Si l'un de ces nouveaux éléments est plus grand que le plus grand élément avec contenu précédent, un nouvel élément PerformanceEntry est également signalé.

Si le plus grand élément avec contenu est supprimé de la fenêtre d'affichage ou même du DOM, il reste le plus grand élément avec contenu, sauf si un élément plus grand est affiché.

Le navigateur cesse de signaler de nouvelles entrées dès que l'utilisateur interagit avec la page (en appuyant dessus, en faisant défiler la page ou en appuyant sur une touche), car l'interaction de l'utilisateur modifie souvent ce qui est visible (ce qui est particulièrement vrai avec le défilement).

À des fins d'analyse, vous ne devez enregistrer dans votre service d'analyse que l'PerformanceEntry envoyée la plus récemment.

Temps de chargement par rapport au temps d'affichage

Pour des raisons de sécurité, le code temporel de rendu des images n'est pas exposé pour les images inter-origines qui ne comportent pas l'en-tête Timing-Allow-Origin. Au lieu de cela, seul leur temps de chargement est exposé (car il est déjà exposé via de nombreuses autres API Web).

Cela peut entraîner une situation apparemment impossible où le LCP est signalé par les API Web comme étant antérieur au FCP. Ce n'est pas le cas, mais cela apparaît uniquement en raison de cette restriction de sécurité.

Dans la mesure du possible, nous vous recommandons toujours de définir l'en-tête Timing-Allow-Origin afin que vos métriques soient plus précises.

Comment les modifications de mise en page et de taille des éléments sont-elles gérées ?

Pour limiter les coûts liés aux performances du calcul et de l'envoi de nouvelles entrées de performances, les modifications apportées à la taille ou à la position d'un élément ne génèrent pas de nouveaux candidats au LCP. Seules la taille et la position initiales de l'élément dans la fenêtre d'affichage sont prises en compte.

Cela signifie que les images qui sont initialement affichées en dehors de l'écran, puis qui passent à l'écran, ne sont pas nécessairement enregistrées. Cela signifie également que les éléments initialement affichés dans la fenêtre d'affichage qui sont ensuite repoussés vers le bas, hors de vue, indiquent toujours leur taille initiale dans la fenêtre d'affichage.

Exemples

Voici quelques exemples de cas où la valeur "Largest Contentful Paint" est atteinte sur quelques sites Web populaires:

Chronologie de Largest Contentful Paint sur cnn.com
Une chronologie de la LCP sur cnn.com.
Chronologie de Largest Contentful Paint sur techcrunch.com
Une chronologie de la LCP sur techcrunch.com.

Dans les deux chronologies ci-dessus, l'élément le plus grand change à mesure que le contenu se charge. Dans le premier exemple, du nouveau contenu est ajouté au DOM, ce qui modifie l'élément le plus grand. Dans le deuxième exemple, la mise en page change et le contenu qui était auparavant le plus grand est supprimé de la fenêtre d'affichage.

Bien que le contenu chargé tardivement soit souvent plus volumineux que le contenu déjà présent sur la page, ce n'est pas nécessairement le cas. Les deux exemples suivants montrent que le LCP se produit avant le chargement complet de la page.

Évolution de Largest Contentful Paint sur instagram.com
Une chronologie du LCP sur instagram.com.
Calendrier de Largest Contentful Paint sur google.com
Une chronologie du LCP sur google.com.

Dans le premier exemple, le logo Instagram est chargé relativement tôt et reste le plus grand élément, même lorsque d'autres contenus sont progressivement affichés. Dans l'exemple de page de résultats de recherche Google, l'élément le plus grand est un paragraphe de texte qui s'affiche avant que les images ou le logo ne soient chargés. Comme toutes les images individuelles sont plus petites que ce paragraphe, il reste l'élément le plus volumineux tout au long du processus de chargement.

Comment mesurer le LCP

La LCP peut être mesurée en laboratoire ou sur le terrain. Elle est disponible dans les outils suivants:

Outils sur le terrain

Outils de l'atelier

Mesurer le LCP en JavaScript

Pour mesurer le LCP en JavaScript, vous pouvez utiliser l'API Largest Contentful Paint. L'exemple suivant montre comment créer un PerformanceObserver qui écoute les entrées largest-contentful-paint et les consigne dans la console.

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

Dans l'exemple ci-dessus, chaque entrée largest-contentful-paint enregistrée représente le candidat au LCP actuel. En général, la valeur startTime de la dernière entrée émise correspond à la valeur LCP. Toutefois, ce n'est pas toujours le cas. Toutes les entrées largest-contentful-paint ne sont pas valides pour mesurer le LCP.

La section suivante présente les différences entre les rapports de l'API et le calcul de la métrique.

Différences entre la métrique et l'API

  • L'API distribue des entrées largest-contentful-paint pour les pages chargées dans un onglet en arrière-plan, mais ces pages doivent être ignorées lors du calcul du LCP.
  • L'API continue de distribuer des entrées largest-contentful-paint après qu'une page a été mise en arrière-plan, mais ces entrées doivent être ignorées lors du calcul du LCP (les éléments ne peuvent être pris en compte que si la page était au premier plan tout le temps).
  • L'API ne signale pas d'entrées largest-contentful-paint lorsque la page est restaurée à partir du cache avant/arrière, mais le LCP doit être mesuré dans ce cas, car les utilisateurs le perçoivent comme des visites de pages distinctes.
  • L'API ne tient pas compte des éléments dans les iFrames, mais la métrique le fait, car ils font partie de l'expérience utilisateur de la page. Sur les pages comportant un LCP dans un iframe (par exemple, une image de couverture sur une vidéo intégrée), une différence apparaît entre CrUX et RUM. Pour mesurer correctement le LCP, vous devez les prendre en compte. Les sous-cadres peuvent utiliser l'API pour signaler leurs entrées largest-contentful-paint au frame parent à des fins d'agrégation.
  • L'API mesure le LCP à partir du début de la navigation, mais pour les pages prérendues, le LCP doit être mesuré à partir de activationStart, car cela correspond au temps LCP tel que l'utilisateur l'a vécu.

Plutôt que de mémoriser toutes ces différences subtiles, les développeurs peuvent utiliser la bibliothèque JavaScript web-vitals pour mesurer le LCP, qui gère ces différences à votre place (dans la mesure du possible, notez que le problème d'iFrame n'est pas couvert):

import {onLCP} from 'web-vitals';

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

Consultez le code source de onLCP() pour obtenir un exemple complet de mesure du LCP en JavaScript.

Que se passe-t-il si l'élément le plus important n'est pas le plus grand ?

Dans certains cas, l'élément (ou les éléments) le plus important de la page n'est pas le plus grand. Les développeurs peuvent donc être plus intéressés par la mesure des temps de rendu de ces autres éléments. Pour ce faire, utilisez l'API Element Timing, comme décrit dans l'article sur les métriques personnalisées.

Améliorer le LCP

Un guide complet sur l'optimisation du LCP est disponible pour vous aider à identifier les délais du LCP sur le terrain et à utiliser les données de laboratoire pour les analyser et les optimiser.

Ressources supplémentaires

Journal des modifications

Il arrive parfois que des bugs soient détectés dans les API utilisées pour mesurer les métriques, et parfois dans les définitions des métriques elles-mêmes. Par conséquent, des modifications doivent parfois être apportées, et ces modifications peuvent apparaître sous la forme d'améliorations ou de régressions dans vos rapports et tableaux de bord internes.

Pour vous aider à gérer ce point, toutes les modifications apportées à l'implémentation ou à la définition de ces métriques seront indiquées dans ce journal des modifications.

Si vous avez des commentaires sur ces métriques, vous pouvez les envoyer dans le groupe Google web-vitals-feedback.