Le projet « Page Experience » et ses trois KPI (LCP, FID et CLS) nommés « Core Web Vitals » arrivent et seront pris en compte par Google en mai 2021. Aussi, il nous a semblé intéressant de consacrer, avant ce lancement, une suite d'articles à ce sujet. Après la revue d'effectif globale du mois dernier, place au premier de ces indicateurs : le LCP (Largest Contentful Paint).

 

Dans la continuité de l’article du mois dernier qui présentait les Core Web Vitals, ainsi que l’arrivée des Page experience signals en Mai 2021, nous allons détailler dans cet article l’un de ces Core Web Vitals (les autres suivront dans les prochains numéros de Réacteur), à savoir le LCP : Largest  Contentful Paint.

Cet indicateur orienté utilisateur peut augmenter en fonctions de différents facteurs. Quel est son fonctionnement, sa méthode de calcul, ainsi que les différents éléments qui peuvent augmenter le LCP et nuire à une bonne expérience utilisateur ? Nous allons aborder tout ces sujets dans cet article qui lui est dédié.

 

Principe du LCP

Deux métriques un peu similaires étaient utilisées auparavant : le FCP (First Contentful Paint), et le FMP (First Meaningful Paint) qui se rapproche le plus du LCP. Cette dernière qui avait amené à des résultats incohérents a poussé Google à ne plus l’utiliser depuis LightHouse 6, afin de s’orienter vers ce nouvel indicateur, le LCP.

Le principe du LCP est de mesurer le chargement de l’élément le plus important dans la partie visible de la fenêtre d’un navigateur (également appelé viewport). Cette métrique User-centric a pour objectif d’être au plus proche du ressenti utilisateur. Un LCP est considéré comme bon quand la peinture du plus grand élément dans la page intervient moins de 2,5 secondes depuis le début du chargement de la page :

 

Figure 1 - Echelle de mesure du score LCP

 

L’élément le plus important est en général une image, une vidéo ou un bloc de texte (titre, paragraphe). Même si cet élément s’étend à l’extérieur de la partie visible de la fenêtre du navigateur, c’est uniquement la partie visible de l’élément à l’écran qui sera prise en compte dans le calcul du LCP. Concernant les images qui sont redimensionnées à partir de leur taille intrinsèque à l’affichage, c’est la dimension affichée qui entrera en ligne de compte. Les images étirées ou agrandies à une taille supérieure ne rapporteront que leur taille intrinsèque.

 

Méthode de mesure

C’est l’API Largest Contentful Paint (https://wicg.github.io/largest-contentful-paint/) qui mesure la dimension à l’affichage des principaux éléments pris en compte. Parmi ces éléments on trouvera :

Un marqueur de performance appelé PerformanceEntry (https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry) de type largest-contentful-paint sera effectuée dès que le navigateur aura peint la première image. Ensuite, si un autre élément (image ou bloc de texte) venait à se charger, une autre entrée PerformanceEntry sera générée, et ainsi de suite, à chaque fois que le plus grand élément de contenu est amené à changer. Un élément peut être considéré comme le plus important, uniquement quand il a été rendu, et qu’il est visible dans le viewport (les éléments qui n’ont pas encore été chargés ne sont d’ailleurs pas considérés comme « rendus »).

Ci-dessous, voici un exemple, dans lequel le LCP est d’abord considéré comme étant un bloc de titre <h1>. Mais avec le chargement de l’image Hero qui intervient dans un deuxième temps, Le LCP devient alors relatif à l’affichage de cette dernière, dont la taille à l’écran est plus importante que le titre (qui a été le premier élément marqué via PerformanceEntry de type largest-contentful-paint).

 

LCP défini par l'affichage d'une image

Figure 2 - LCP défini par l'affichage d’une image

 

Pour prendre un autre exemple ci-dessous, sur une page contenant une liste de différents articles (combo texte + image pour chaque article), le navigateur enverra d’abord un marqueur PerformanceEntry (qui fera référence à une balise de titre sur 4 lignes en bas de page). Mais la disposition changera au fur et à mesure que de nouveau éléments modifient le DOM, jusqu’à ce qu’un titre plus important s’affiche à l’écran prenne le relais (en haut de page cette fois). Enfin, quand l'image principale est chargée, un autre marqueur PerformanceEntry sera généré dans le navigateur, et l’image sera alors considérée comme relative au LCP une fois affichée.

 

Modification du LCP au cours du chargement des éléments

Figure 3 - Modification du LCP au cours du chargement des éléments

 

Attention, le navigateur arrêtera de signaler les nouvelles entrées via l’API dès que l’utilisateur rentrera en interaction avec la page Web (pression touche, scroll, touché sur l’écran), cette interaction pouvant modifier l’affichage.

Ce système de mesure du LCP comptabilise les éléments de façon unique : un bloc d’images qui contiendrait plusieurs images ne sera pas nécessairement l’élément le plus important. Dans l’exemple ci-dessous, le paragraphe de texte est considéré comme étant l’élément principal, car il est plus large que chacune des images de façon individuelle.

 

Elément texte considéré comme l'élément le plus important pour le calcul du LCP

Figure 4 - Elément texte considéré comme l'élément le plus important pour le calcul du LCP

 

Par ailleurs, si un élément déjà chargé hors du viewport, était amené à s’afficher dans le viewport après une modification du DOM, ce dernier ne serait pas pris en compte.

 

Intérêt du LCP

Le LCP est une bonne alternative au DOMContentLoaded (évenement émis quand le document HTML initial a été chargé et analysé), car il prend en compte le rendu de l’élément le plus important qui sera visible pour l’internaute. Il mesure également tout ce qui est nécessaire pour rendre le contenu clé d’une page : résolution DNS, certificat SSL/TLS, TTFB (Time To First Byte), code HTML et styles CSS, fichiers JavaScript bloquants le rendu au-dessus de la ligne de flottaison, etc.

Le LCP n’intervient qu’après plusieurs étapes quand une page Web est demandée par un navigateur :

    1. HTML récupéré et interprété ;
    2. Éléments relatifs au chemin critique de rendu téléchargés interprétés ;
    3. Éléments relatifs au LCP téléchargé et rendus (image, video, …).

Plus les documents seront vites récupérés (temps de réponse, poids des fichiers, etc.), meilleurs seront les effets sur le LCP. Si l’on regarde dans le détail, plusieurs éléments peuvent retarder le LCP :

  • Requête DNS et TLS handshake (échange des certificats, chiffrement des données) ;
  • TTFB (temps que le serveur met à renvoyer le premier octet) ;
  • Téléchargement du HTML et interprétation de ce dernier, téléchargement des ressources complémentaires ;
  • Construction du DOM (Document Object Model) et CSSOM (CSS Object Model) ;
  • Interprétation du Javascript et modification de l’arbre de rendu.

Ce sont autant d’étapes qui peuvent impacter le LCP. Nous allons voir comment chacune d’entre elles peuvent être optimisées afin d’avoir un KPI.

 

Comment améliorer le LCP ?

Parmi les facteurs d’amélioration du LCP, voici les principaux axes d’optimisation afin d’améliorer la durée de chacune de ces étapes.

Temps de réponse serveur

Afin d’améliorer le temps de réponse serveur, l’utilisation d’un CDN permettra de servir plus rapidement les utilisateurs en fonction de leur localisation. En parallèle, la mise en place d’un cache performant permettra de servir des pages statiques (déjà calculées), plutôt que de réinterpréter inutilement des scripts de l'applicatif côté serveur (avec des connexions aux bases de données), pour régénérer des pagesqui seront au final identiques pour chaque utilisateur. Des reverse proxy comme Varnish ou Nginx sont des solutions de cache très puissantes en ce sens. Fasterize propose un service de cache avec une configuration simplifiée via l’interface utilisateur.

Des ressources tierces peuvent également ralentir le chargement d’éléments externes. Dans ce cas, l’utilisation de rel=preconnect permettra d’établir une connexion avec un autre domaine, en amont du téléchargement des resosurces associées à ce dernier :

<link rel="preconnect" href="https://example.com" />

Dans le cas où la pré-connexion ne serait pas supportée par certains navigateurs (https://caniuse.com/link-rel-preconnect), un dns-prefetch (résolution DNS anticipée) pourra être utilisé en solution de fallback :

<head>

<link rel="preconnect" href="https://example.com" />

<link rel="dns-prefetch" href="https://example.com" />

</head>

JS et CSS qui bloquent le rendu

Une fois le HTML téléchargé, le navigateur analyse le document ligne par ligne pour trouver des ressources dans le chemin critique. Le CSS et le JavaScript dans la partie <head> sont prioritaires, puis les images dans le corps du document sont téléchargées dans l'ordre où elles apparaissent.

Si l'analyseur du navigateur voit une balise de script bloquante (c'est-à-dire sans attribut async ou defer), il arrête tout ce qu'il fait pendant la récupération, l'analyse et l'exécution de ce script.

Les scripts doivent toujours être soit asynchrones, lorsque l'ordre d'exécution n'est pas important, soit différés lorsque l'ordre d'exécution est important.

Différence entre async et defer

Figure 5 - Différence entre async et defer

 

Afin de s’assurer que l’ensemble des scripts et CSS sont utiles pour chaque template analysée, vous pouvez utiliser l’outil « Show Coverage » du navigateur Chrome (Ctrl + Shift +P dans l’Inspecteur d’éléments) :

 

ShowCoverage dans Google Chrome

Figure 6 - ShowCoverage dans Google Chrome

 

Nous constatons ici que le fichier blocks.style.css n’est pas utilisé pour la page testée, ce qui génère une requête inutile, et augmente le temps d’évaluation des scripts par le navigateur.

Les styles qui sont critiques pour l’affichage du contenu principal peuvent être intégrés in-line (c'est à dire directement dans le code HTML, partie <head>) pour éviter un aller-retour vers le serveur pour récupérer le fichier CSS. Certains scripts permettent de faciliter cette tâche en identifiant les CSS critiques qui pourront être placé dans le code de la page :

https://github.com/filamentgroup/criticalCSS

https://github.com/pocketjoso/penthouse

Enfin, la minification (suppression des caractères inutiles : espace, tabulation retour à la ligne, etc.) et la compression (via Gzip, Brotli) des fichiers texte JS et CSS peut réduire leur poids et accélérer leur chargement.

Temps de chargement des ressources

Les fichiers images sont souvent un facteur ralentissant le LCP. Pour éviter que les images ne soient pénalisantes, il est recommandé de fournir des images Responsives, adaptées en fonction de l’appareil (et non de redimensionner de grandes images à l’affichage), via les attributs images srcset (ou la balise <picture> d’HTML 5).

Une bonne compression permettra également d’accélérer le chargement de ces ressources média, le format WebP étant particulièrement performant (ce dernier n’étant pas supporté par tout les navigateurs, une solution de fallback sera nécessaire).

Un pré chargement des images pouvant être liées au LCP (Hero image) peut également être effectué (dans la partie <head>) :

<link

rel="preload"

as="image"

href="wolf.jpg"

imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w"

imagesizes="50vw"

/>

 

Rendu JS côté client

Des sites utilisent énormément JavaScript côté client pour rendre les pages directement dans le navigateur. Des Frameworks comme React ou Angular permettent de modifier de façon importante le contenu d'une page web côté client plutôt que sur le serveur.

Un site rendu côté client peut avoir un impact important sur le LCP, si beaucoup de JavaScript est utilisé. Si aucune optimisation n'est mise en place, les utilisateurs ne pourront pas interagir avec le contenu de la page avant que tous les fichiers JavaScript essentiels aient été téléchargés et exécutés.

La mise en place de Server-Side-Rendering peut permettre de limiter le temps d’exécution du JS côté client, et donc d’avoir un meilleur LCP. Cela demandera cependant un système de cache efficace, pour éviter de surcharger le serveur (l’exécution du JS étant consommatrice de ressources).

 

Comment suivre le LCP

Les outils de Synthetic Monitoring comme LightHouse, WebPageTest ou encore l’extension Chrome « Web Vitals » (https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma) seront un bon moyen de tester le LCP sur différentes typologies de pages.

Pour avoir une vision Rum (Real User Monitoring) avec de vraies données utilisateurs (et non des tests unitaires), PageSpeedInsights vous permettra de remonter les informations issues du ChromeUserExperience, avec des données réelles sur les 28 derniers jours.

Toutes les URL n’ayant pas forcément suffisamment de données pour que Google puisse les agréger dans son rapport, et cet indicateur pouvant fortement varier d’une page à l’autre, une bonne solution alternative sera de passer par la librairie Web Vitals qui remontera le LCP de vos utilisateurs directement dans Google Analytics : https://github.com/GoogleChrome/web-vitals

Pour conclure, le LCP est une mesure importante, qui inclut de nombreuses étapes liées au chargement d’une page Web, et demande la prise en compte de plusieurs éléments : chacun des critères passés en revue peut avoir une influence, mais c’est la combinaison de toutes les optimisations (liste non exhaustive) qui fera la différence.

 

 

Aymeric Bouillat, Consultant SEO senior chez Novalem (https://www.novalem.fr/)