SEO: Pourquoi mon site n’est pas sur Google ? LCP, l’histoire secrète de la WebPerf

Raphaël Tuong Tho VO
ekino-france
Published in
10 min readApr 12, 2024

Comment sont calculés les résultats de recherche sur Google ?

Parmi tous les paramètres pour calculer la position d’un site, un élément important est la facilité d’utilisation des pages Web. En d’autres termes :

Notre moteur de recherche prend également en compte la facilité d’utilisation du contenu. Si deux pages Web sont plus ou moins identiques, celle que les internautes trouvent la plus accessible sera peut-être plus performante.

Ainsi, parmi les signaux de l’expérience sur la page qui jouent un rôle pour le classement, nos systèmes évaluent l’ergonomie mobile et la vitesse de chargement, deux aspects importants pour les mobinautes.

TLDR: La performance de votre site web joue un rôle important pour améliorer le classement de votre site dans les résultats de Google.

Vous devez donc optimiser les performances de votre site Web, mais cela peut être généralement difficile, nécessitant beaucoup de temps, d’efforts et d’argent pour auditer et réaliser les améliorations nécessaires. Mais comment manger une baleine ? Vous la coupez en petits morceaux, et l’un de ces petits morceaux est le Largest Contentful Paint (LCP).

Largest Contentful Paint (LCP): Alors, Raphaël, qu’est-ce que c’est ?

I am glad you ******* asked — Paul Taylor au Toboggan, ce jeudi. Photo DR

La métrique “Largest Contentful Paint” (LCP) indique le délai d’affichage du plus grand bloc d’image ou de texte visible dans la fenêtre d’affichage, par rapport au premier chargement de la page.

TLDR: Le Largest Contentful Paint (LCP) est le temps nécessaire pour que le plus grand élément visuel, qu’il s’agisse d’une image ou d’un texte, s’affiche dans la fenêtre d’affichage (viewport) lors du premier chargement de votre page.

TLDR: Mais pour vos enfants de moins de 5 ans, c’est le temps nécessaire pour trouver le plus grand gâteau dans la pâtisserie.

Mais pourquoi le LCP est important ?

Le LCP est crucial car il fait partie des nombreuses mesures qui permettent de calculer le temps de chargement et la durée avant que votre site Web soit visible par vos utilisateurs. Et si vous voulez garder vos utilisateurs, les encourager à effectuer un achat sur votre site, ou les inciter à rester suffisamment longtemps pour lire cet article, il est essentiel d’avoir un bon score de LCP.

Le valeur en seconde pour LCP: Bon (≤2.5s) -> À améliorer(2.5–4s) -> Mauvais(> 4s)

Maintenant, voyons comment analyser la valeur du LCP de votre site.

Quelques outils sont à votre disposition:

  1. PageSpeed Insight — https://pagespeed.web.dev/
  2. Lighthouse — Un outil de Chrome Developer Tool
  3. Treo Site Speed — https://treo.sh/sitespeed
Le LCP ne passe pas sur PageSpeed Insight

Est-ce vraiment important?

Est-ce réellement important ? Oui, c’est crucial et j’aimerais vous présenter un tableau intéressant comportant des valeurs pertinentes:

Ce tableau illustre la corrélation entre l’optimisation du LCP, le taux de conversion et les revenus. En général, ce n’est pas seulement le LCP qui contribue seul aux résultats, mais une combinaison d’optimisation de nombreuses métriques qui garantit un bon résultat. Aujourd’hui, on se concentre sur le LCP.

Vous êtes là ? Vous êtes convaincus ? Comment identifie-t-on le Largest Contentful ?

Vous avez compris ce qu’est le LCP, mais votre site web contient de nombreux éléments HTML. Quel élément est le sujet à traiter ?

La liste d’élément important:

1. Éléments <img>

2. Éléments <image> dans un élément <svg>

3. Éléments <video> avec une image poster (le temps de chargement de l'image poster est utilisé)

4. Un élément avec une image de fond chargée via la fonction url() (par opposition à un dégradé CSS)

5. Éléments au niveau du bloc contenant des nœuds de texte ou d’autres éléments enfants d’éléments de texte intégrés au niveau du bloc.

6. Première image peinte pour la lecture automatique des éléments <video> (depuis août 2023)

7. La première image d’un format d’image animée, par exemple un GIF animé (depuis août 2023)

Pour 1., 2., 4., et 5., c’est assez clair, soit un bloc de texte, soit une image. Mais pour le reste, on peut comprendre que c’est l’image “poster” de la vidéo ou un fichier animé de format GIF.

Un exemple sur MDN:

<!-- Un exemple simple -->
<video src="fichiervideo.webm" autoplay poster="vignette.jpg">
Votre navigateur ne permet pas de lire les vidéos. Mais vous pouvez toujours
<a href="fichiervideo.webm">la télécharger</a> !
</video>

Comment optimiser cet élément ?

Au lieu de parler de théorie, pourquoi ne pas pratiquer ensemble pour découvrir comment faire?

Tout d’abord, vous pouvez cloner ma démo ici. C’est une démo simple et facile d’utilisation mais n’hésitez pas à faire une PR ou à posez vos questions.

Ma démo est faite avec Vite et Bootstrap donc vous pouvez l’installer et commencer rapidement avec les commandes suivantes:

# Cloner mon démo
git clone https://github.com/thovo/web-vitals-demo.git
# Basculer sur le repo
cd web-vitals-demo
# Installer les dependencies
npm i
# Lancer l'application avec la commande npm
npm run dev

Maintenant, vous pouvez y accéder ici:

http://127.0.0.1:5173/

  1. Première question: Quel élément est le LCP ?

La réponse se trouve juste en dessous mais prenez le temps de réfléchir avant de scroller ;)

Un screenshot de démo

La réponse: La première image du slider. J’espère que vous avez identifié correctement l’élément LCP, mais s’il y a eu une erreur, ne vous inquiétez pas, vous êtes ici pour apprendre.

Dans la démo, je simule le fonctionnement de framework JS d’aujourd’hui comme Angular, React, ou Vue par utiliser le JS pour générer le slider.

<div id="simpleCarousel" 
class="carousel slide h-25 mh-25"
style="max-height: 400px;min-height: 400px;">

</div>
function generateCarousel() {
let carouselIndicator = '';
let carouselItems = '';
for (let i = 1; i <= carouselData.length; i++) {
carouselIndicator += generateCarouselIndicator(i - 1);
carouselItems += generateCarouselInnerItem(carouselData[i - 1], i);
}
return `
<div class="carousel-indicators">
${carouselIndicator}
</div>
<div class="carousel-inner" style="max-height: 400px;">
${carouselItems}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#simpleCarousel"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#simpleCarousel"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
`;
}

On a trouvé l’élément LCP, et on voudrait que cet élément commence à se charger en premier juste après le chargement de la page HTML.

Accrochez-vous, la suite est plus technique ;)

Le temps complet de chargement d’un élément LCP se décompose en 4 parties:

  1. Time to first byte(TTFB): Le délai entre le moment où l’utilisateur charge la page et le navigateur reçoit le premier octet de la réponse du document HTML
  2. Resource load delay: Le delta entre TTFB et le moment où le navigateur commence à télécharger la ressource LCP
  3. Resource load time: Le temp de chargement de la ressource LCP
  4. Element render delay: Le delta entre le moment où la resource a fini de charger et le rendu complet

Pour optimiser le LCP, nous devons optimiser chacune des quatre parties. Dans quelque cas, lorsque vous optimisez le temps d’une partie, cela ne modifie pas le LCP, car ce temps est attribué à une autre partie. Par exemple, pour réduire le temps de téléchargement de l’image LCP, vous pouvez utiliser les formats plus récents comme AVIF ou WebP. Cela réduira le temps de chargement des resource load time mais cela attribuera le temps au rendu, ou ce que l’on pourrait appeler ‘element render delay.’

Dans notre démo, le LCP est l’image 1.jpg

2. Optimiser le LCP (👈Le plus important de cet article)

Réduire Resource load delay:

L’idée de cette étape est réduire le temps de chargement de LCP. En générale, il y a deux astuces à faire:

  • Quand la resource est découvert
  • Quelle priorité de la resource

Pour découvrir rapidement le LCP, on peut utiliser une mechanique de navigateur: preload scanner:

  • LCP est une image: Vous pouvez indiquer l’image par src ou srcset dans HTML, ou si c’est une image du fond, charger par background dans CSS, vous pouvez utiliser link rel=”preload” pour demander le navigateur de charger le LCP avant les autres resources
  • LCP est une node de texte: C’est pareil, vous pouvez charger la police avec link rel=”preload”

Alors, j’applique directement cette technique pour notre image LCP

<link rel="preload" as="image" href="/images/1.jpg" type="image/jpg">

Le résultat:

Notre LCP est pre-chargé avec preload

Le LCP n’est pas découvert dans les cas suivant:

  • L’image LCP est ajoutée par JavaScript, car il faut attendre que le script ait fini de se charger.
  • L’image LCP est utilisée avec lazyload , parce que la technique lazy load va bloquer le chargement de notre image LCP
  • L’image de fond, chargée par CSS, parce qu’il faut attendre le chargement du fichier CSS

Pour éviter de bloquer le LCP, il faut le charger avec la priorité plus importante. Pour monter la priorité, on peut utiliser fetchpriority=”high” . Revenir sur notre code, comment faire?

<link rel="preload" as="image" href="/images/1.jpg" type="image/jpg" fetchpriority="high">
Le résultat est mieux, il est chargé en priorité, mais il faut attendre le script JS pour render

Maintenant, il faut que nous déplacer le logique dans le script main.js pour générer le carousel à notre HTML, l’image peut être chargé directement

Dans ma démo, vous pouvez copier directement la génération de div id=”simpleCarousel” et coller dans le ficher index.html . Dans fichier main.js vous enlevez l’appel de la fonction setupCarousel et parce qu’on n’a plus besoin d’appeler main.js , on peut l’enelver.

import './style.css';
import { setupCarousel } from './js/carousel';


// setupCarousel(document.querySelector('#simpleCarousel'));

On a fait l’action pour laisser le navigateur découvrir notre LCP plus rapidement par utiliser preload et afficher directement le LCP dans HTML mais on image un nouveau scénario, quand on a beaucoup de resources importantes avec preload , on doit décider quelle resource est plus prioritaire, et on baisse la priorité des autres.

<!-- On peut mettre fetchpriority pour chaque image pour changer l'ordre de télécharger -->
<img src="/images/1.jpg" class="d-block w-100 h-50" alt="1" fetchpriority="high">
<img src="/images/2.jpg" class="d-block w-100 h-50" alt="2" fetchpriority="low">
<img src="/images/3.jpg" class="d-block w-100 h-50" alt="3" fetchpriority="low">

Il faut éviter aussi l’attribut comme loading=”lazy” dans votre img , il bloque le chargement de cette image.

L’image LCP est chargé en plus priorité avec notre changement

Réduire element render delay

L’élément n’est pas toujours faire le rendering de qu’il a fini télécharger, le plupart de temps, il faut attendre les autres, par exemple:

  1. Les gros stylesheets ou scripts de finir téléchargement
  2. Il attend le JS charger le LCP
  3. Il attend le stylesheet charger la ligne background
  4. Le script prend trop de temps pour éxecuter

Et on a aussi des techniques pour chaque problème.

Réduire ou utiliser inline style

Ce n’est pas une nouvelle technique, depuis longtemps, on peut mettre le style inline pour les éléments présentent First Contentful Paint, l’idée est au lieu d’attendre de charger un gros fichier CSS qui contient plein de style on n’a pas vraiment besoin jusqu’à quand la page a fini charger, on mise les styles essentiels directement sur la partie du LCP. Cette style inline va être téléchargé en même temps avec HTML.

Une autre technique est réduit le gros fichier CSS pour que le navigateur peut les charger plus rapide. Comment faire?

  • Enlever les CSS ne sont pas nécessaires ou inutilisés
  • Diviser le gros fichier en petit morceaux, garder le fichier essentiel et charger les autres après
  • Réduisez et compressez les fichiers CSS

Cette technique n’est pas seulement réservé pour CSS, vous pouvez aussi appliquer pour Javascript. Aujourd’hui, sur les frameworks comme Angular, ou React, avec l’aide de Webpack, vous trouverez souvent les fichiers JS en petit chunks et déjà compressée.

Pour Javascript, une autre remarque est aussi très important est diviser les tâches longs en plusieurs petites tâches.

Toujours diviser en petites tâches

Ce n’est pas difficile pour voir pourquoi, comme nous, Javascript peut exécuter une tâche pour fois, une tâche longue va bloquer complètement et prendre beaucoup de temps pour finir, l’utilisateur faut attendre cette exécution et il peut faire presque rien.

Enfin et surtout, deux dernières astuces à considérer:

  • Réduire la taille du fichier en utilisant les nouveaux format mordernes comme WebP, AVIF,…etc
  • Réduire le temps de transport entre le server et la destination avec content delivery network (CDN).

Conclusion

En conclusion, l’optimisation du Largest Contentful Paint (LCP) est une étape cruciale pour améliorer l’expérience utilisateur globale et les performances d’un site web. En se concentrant sur des temps de réponse du serveur efficaces, en optimisant la livraison des ressources et en donnant la priorité au chargement du contenu essentiel comme l’image, nous pouvons réduire considérablement le valeur du LCP et créer un environnement en ligne plus réactif et engageant.

La mise en œuvre de bonnes pratiques telles que la minimisation des ressources bloquant le rendu, l’utilisation du cache du navigateur et l’optimisation des images sont des composants essentiels du processus d’optimisation. La surveillance régulière des performances et l’analyse à l’aide d’outils tels que Google PageSpeed Insights ou Lighthouse peuvent aider à identifier les goulots d’étranglement potentiels et à guider d’autres améliorations. De plus, rester informé des dernières technologies et techniques de développement web est crucial pour rester à la pointe des normes émergentes et garantir une optimisation continue du LCP.

Finalement, un engagement envers un raffinement continu et une adaptation aux meilleures pratiques émergentes est essentiel pour un succès soutenu dans l’optimisation du LCP. En priorisant l’expérience utilisateur et en offrant des pages web plus rapides et plus efficaces, nous contribuons non seulement à l’amélioration des performances, mais aussi à une satisfaction et une implication accrues des utilisateurs. À mesure que les sites web continuent d’évoluer, l’optimisation du LCP reste un aspect fondamental pour offrir une expérience en ligne fluide et agréable aux visiteurs.

Références

  1. Facilité utilisation des pages Web -https://www.google.com/search/howsearchworks/how-search-works/ranking-results/#usability
  2. Largest Contentful Paint (LCP) — https://web.dev/articles/lcp?hl=fr
  3. Case studies — https://web.dev/case-studies ou https://wpostats.com/?sjid=15479569239720511772-EU

Autres resources

  1. Réseaux de diffusion de contenu (CDN) — https://web.dev/articles/content-delivery-networks?hl=fr
  2. Pour optimiser l’image avec les frameworks:
    - Angular: NgOptimizedImage — https://angular.io/api/common/NgOptimizedImage
    - Next: next/image — https://nextjs.org/docs/app/building-your-application/optimizing/images

--

--

Raphaël Tuong Tho VO
ekino-france

I think the best way to remember and learn thing is writing it out. And as I get older, I usually forget a lot of things. One more reason to start writing.