Pour une bonne expérience utilisateur, les pages doivent s’afficher le plus vite possible. En effet, attendre que le contenu apparaisse à l’écran est un facteur d’insatisfaction pour les internautes.
Pour évaluer le temps nécessaire pour qu’une page s’affiche, le First Contentful Paint (FCP) mesure le temps nécessaire au rendu du contenu initial du DOM, mais ne capture pas le temps nécessaire pour le rendu du contenu le plus important en termes de taille (généralement le plus pertinent pour les utilisateurs).
Le Largest Contentful Paint (LCP) est une métrique Core Web Vitals qui indique le moment où le plus grand élément de contenu devient visible dans le viewport. Il peut être utilisé pour déterminer quand le contenu principal de la page est affiché à l’écran.
Nous allons voir dans les sections suivantes les causes les plus fréquentes d’un mauvais LCP, et comment les adresser :
- Des temps de réponse serveur longs
- Des JavaScript et CSS qui bloquent le rendu
- Des ressources qui mettent du temps à se charger
- Le Client-side rendering (rendu côté client)
(NdT : nous proposons régulièrement des techniques et astuces pour vous aider à améliorer l’ensemble de vos métriques webperf dans notre newsletter mensuelle, vous pouvez vous y abonner ici.)
Largest Contentful Paint et temps de réponse serveur lents
Plus il faut de temps à un navigateur pour recevoir du contenu du serveur, plus il faut de temps pour afficher quoi que ce soit à l’écran. Un temps de réponse du serveur plus rapide améliore directement chaque métrique de chargement de page, y compris le LCP.
Avant toute chose, améliorez la façon et l’emplacement depuis lequel votre serveur gère votre contenu. Observez votre Time to First Byte (TTFB) pour mesurer les temps de réponse de votre serveur.
Vous pouvez améliorer votre TTFB de différentes manières que nous allons détailler :
- Optimisez votre serveur
- Rapprochez le contenu de vos utilisateurs grâce à un CDN
- Mettez vos ressources en cache
- Priorisez les contenus HTML en cache
- Rendez la connexion avec les tiers rapide
Optimiser votre serveur
Vous exécutez des requêtes coûteuses qui prennent beaucoup de temps à votre serveur ? Ou existe-t-il d’autres opérations complexes côté serveur qui retardent l’arrivée du contenu sur la page ? L’analyse et l’amélioration de l’efficacité de votre code côté serveur améliorera directement le temps nécessaire au navigateur pour recevoir les données.
Au lieu de servir immédiatement une page statique suite à une requête du navigateur, de nombreux frameworks côté serveur doivent créer la page web de manière dynamique. En d’autres termes, plutôt que d’envoyer simplement un fichier HTML complet et tout prêt lorsque le navigateur le demande, les frameworks doivent effectuer des opérations pour construire la page. Cela peut être dû aux résultats en attente d’une requête en base de données, ou même au fait que les composants doivent être générés dans le balisage par un framework UI (tel que React). De nombreux frameworks qui s’exécutent côté serveur proposent des recommandations pour accélérer ce processus (en voici quelques-unes (en anglais) pour améliorer les performances d’un serveur surchargé).
Utiliser un CDN
Un Content Delivery Network (CDN) est un réseau de serveurs répartis dans différentes zones géographiques. Si le contenu de votre page web est hébergé sur un seul serveur, votre site web se chargera plus lentement pour les utilisateurs qui sont géographiquement éloignés car les requêtes de leur navigateur doivent littéralement voyager à travers le monde. Pensez à utiliser un CDN pour vous assurer que vos utilisateurs n’auront pas besoin d’attendre suite aux requêtes réseau vers des serveurs éloignés.
Mettre vos ressources en cache
Si votre code HTML est statique et n’a pas besoin de changer à chaque requête, la mise en cache peut éviter de le recréer inutilement. En stockant une copie du code HTML généré, la mise en cache côté serveur peut réduire le TTFB et l’utilisation des ressources.
Selon vos outils, il existe de nombreuses façons d’appliquer la mise en cache côté serveur :
- configurer un reverse proxy (Varnish, nginx) pour servir le contenu mis en cache ou agir comme un serveur de cache lorsqu’il est installé devant un serveur d’applications ;
- configurer et gérer le comportement du cache de votre fournisseur de Cloud (Firebase, AWS, Azure) ;
- utiliser un CDN qui fournit des serveurs edge afin que votre contenu soit mis en cache et stocké au plus près de vos utilisateurs.
Servir en priorité les pages HTML en cache
Une fois installé, un Service Worker s’exécute en arrière-plan du navigateur et peut récupérer les requêtes du serveur. Cette programmation du contrôle du cache permet de cacher tout ou partie du contenu de la page HTML et de ne mettre à jour le cache que lorsque le contenu a changé.
Le graphique suivant montre comment les distributions du Largest Contentful Paint ont été réduites sur un site à l’aide de cette technique :
Distribution du Largest Contentful Paint avec et sans Service Worker
Le graphique montre la distribution du LCP pour un seul site sur 28 jours, segmentée par état du Service Worker. Vous remarquerez à quel point bien plus de pages ont un meilleur LCP après la mise en place pour ces pages d’une stratégie cache-first via le Service Worker (partie bleue du graphique).
Pour en savoir plus sur les techniques pour servir des pages HTML cache-first en totalité ou en partie, vous pouvez consulter cette ressource (en anglais) : Smaller HTML Payloads with Service Workers.
Établir rapidement des connexions avec des tiers
Les requêtes serveur vers des origines tierces peuvent également avoir un impact sur le LCP, surtout si elles sont nécessaires pour afficher un contenu critique sur la page. Utilisez rel = « preconnect » pour informer le navigateur que votre page a l’intention d’établir une connexion dès que possible.
[pastacode lang= »markup » manual= »%3Clink%20rel%3D%22preconnect%22%20href%3D%22https%3A%2F%2Fexample.com%22%3E » message= » » highlight= » » provider= »manual »/]
Vous pouvez aussi utiliser dns-prefetch pour des résolutions DNS plus rapides.
[pastacode lang= »markup » manual= »%3Clink%20rel%3D%22dns-prefetch%22%20href%3D%22https%3A%2F%2Fexample.com%22%3E » message= » » highlight= » » provider= »manual »/]
Bien que ces deux hints fonctionnent différemment, vous pouvez utiliser dns-prefetch en solution de remplacement pour les navigateurs qui ne supportent pas preconnect.
[pastacode lang= »markup » manual= »%3Chead%3E%0A%C2%A0%E2%80%A6%0A%C2%A0%3Clink%20rel%3D%22preconnect%22%20href%3D%22https%3A%2F%2Fexample.com%22%3E%0A%C2%A0%3Clink%20rel%3D%22dns-prefetch%22%20href%3D%22https%3A%2F%2Fexample.com%22%3E%0A%3C%2Fhead%3E » message= » » highlight= » » provider= »manual »/]
Pour plus d’informations sur ce sujet, vous pouvez consulter cette ressource (en anglais) : Establish network connections early to improve perceived page speed
Largest Contentful Paint : les JavaScript et CSS qui bloquent le rendu
Avant qu’un navigateur puisse rendre un contenu quel qu’il soit, il doit analyser le balisage HTML dans le DOM. L’analyseur (parser) HTML s’arrêtera s’il rencontre des feuilles de style externes (<link rel = « stylesheet »>) ou des balises JavaScript synchrones (<script src = « main.js »>).
Les scripts et les feuilles de style sont tous deux des ressources qui bloquent le rendu et qui retardent le FCP, et par conséquent le LCP. Différez tout code JavaScript et CSS non critique pour accélérer le chargement du contenu principal de votre page web.
Réduire le temps de blocage des CSS
Assurez-vous que seule la quantité minimale de CSS nécessaire bloque le rendu sur votre site en appliquant les techniques suivantes (NdT : notre moteur permet d’automatiser certaines de ces techniques) :
- minifier le CSS
- différer le CSS non critique
- inliner le CSS critique
Minifier le CSS
Pour une meilleure lisibilité, les fichiers CSS peuvent contenir des éléments tels que des espaces, indentations ou commentaires… Mais ces caractères et ces espaces sont inutiles pour le navigateur et la minification permet de les supprimer. Tout ce qui permet de minimiser le blocage du CSS améliore la vitesse et le temps nécessaire pour restituer entièrement le contenu principal de la page (LCP).
Si vous utilisez un générateur de bundle ou un outil de build, incluez un plugin approprié pour réduire les fichiers CSS sur chaque build :
- pour webpack : optimize-css-assets-webpack-plugin
- pour Gulp : gulp-clean-css
- pour Rollup : rollup-plugin-css-porter
Pour aller plus loin, vous pouvez consulter ce guide (en anglais) : Minify CSS.
Différer les CSS non-critiques
Utilisez l’onglet Coverage dans Chrome DevTools pour détecter tous les CSS non utilisés sur votre page web.
Puis, pour optimiser :
- Supprimez tout CSS inutilisé ou déplacez-le vers une autre feuille de style s’il est utilisé sur une page précise de votre site.
- Pour tout CSS non nécessaire au rendu initial, utilisez loadCSS et chargez les fichiers en asynchrone à l’aide de rel= »preload » et onload.
[pastacode lang= »css » manual= »%3Clink%20rel%3D%22preload%22%20href%3D%22stylesheet.css%22%20as%3D%22style%22%20onload%3D%22this.rel%3D’stylesheet’%22%3E » message= » » highlight= » » provider= »manual »/]
Exemple d’amélioration du LCP : avant et après avoir différé le CSS non critique
Pour plus de détails sur le sujet, vous pouvez consulter ce guide (en anglais) : Defer non-critical CSS.
Inliner les CSS critiques
Inlinez les CSS du chemin critique utilisés au-dessus de la ligne de flottaison en les incluant directement dans la balise <head>.
CSS critique inliné
Inliner les styles importants réduit les allers-retours pour récupérer le CSS critique. Le defer du reste réduit aussi le temps de blocage CSS.
Si vous ne pouvez pas ajouter manuellement des styles inlinés à votre site, vous pouvez par exemple utiliser une librairie pour automatiser ce processus. Quelques exemples :
- Critical, CriticalCSS et Penthouse sont des packages qui extraient et inlinent les CSS au-dessus de la ligne de flottaison.
- Critters est un plugin webpack qui inline le CSS critique et lazyloade le reste.
- Ndt : notre moteur permet aussi d’automatiser l’optimisation des CSS
Exemple d’amélioration de LCP : avant et après l’inlining des CSS critiques
Pour en savoir plus sur le sujet, vous pouvez consulter cette ressource (en anglais) : Extract critical CSS.
Réduire le temps de blocage du JavaScript
Chargez et envoyez la quantité minimale de JS nécessaire aux utilisateurs. Réduire la quantité JS bloquant se traduit par un rendu plus rapide, et par conséquent un meilleur Largest Contentful Paint.
Cela peut être réalisé en optimisant vos scripts de différentes manières :
- Minifiez et compressez vos fichiers JavaScript
- Différez le JS inutilisé
- Réduisez les polyfills inutilisés
Cet article sur l’optimisation du FID précise les techniques pour réduire le temps de blocage du JS.
L’impact des ressources qui mettent du temps à se charger sur le Largest Contentful Paint
Bien qu’une augmentation du temps de blocage par des CSS ou du JavaScript entraîne directement une baisse des performances, le temps nécessaire pour charger de nombreux autres types de ressources peut également affecter la vitesse d’affichage. Les familles d’éléments qui affectent LCP sont :
- les éléments <img>
- les éléments <image> à l’intérieur d’un élément <svg>
- les éléments <video> (si spécifié, l’image poster est utilisée pour mesurer le LCP)
- les éléments avec une image d’arrière-plan chargée via la fonction url() (par opposition à un dégradé CSS)
- les éléments de niveau Block contenant des nœuds texte ou d’autres éléments de texte de type inline.
Le temps qu’il faut pour charger ces éléments, s’ils sont rendus au-dessus de la ligne de flottaison, aura un effet direct sur LCP. Il existe plusieurs façons de s’assurer que ces fichiers sont chargés aussi rapidement que possible, que nous allons détailler :
- optimiser et compresser les images
- précharger les ressources importantes
- compresser des fichiers texte
- l’adaptive serving
- mettre en cache les ressources à l’aide d’un Service Worker
Optimiser et compresser les images
Pour de nombreux sites, les images sont le plus grand élément visible lorsque le chargement de la page est terminé. Les images “hero”, les grands carrousels ou les bannières sont des exemples courants.
L’image est le plus grand élément sur la page (design.google)
L’amélioration du temps de chargement et de rendu de ces types d’images accélérera directement le LCP. Pour y parvenir :
- Envisagez de ne pas utiliser une image en premier lieu. Si ce n’est pas pertinent pour le contenu, supprimez-la.
- Compressez les images (Ndt : notre moteur permet d’optimiser automatiquement et intelligemment les images).
- Convertissez les images dans des formats plus récents (JPEG 2000, JPEG XR ou WebP).
- Utilisez des images responsive.
- Envisagez d’utiliser un CDN d’image.
Voici un guide complet sur l’optimisation des images (en anglais) : Optimize your images. (NdT : et ici sur la façon dont notre moteur redimensionne les images).
Précharger les ressources importantes
Parfois, des ressources importantes qui sont déclarées ou utilisées dans un fichier CSS ou JavaScript donné peuvent être récupérées plus tard que vous ne le souhaitez, comme une font profondément cachée dans l’un des nombreux fichiers CSS d’une application.
Si vous savez qu’une ressource particulière doit être priorisée, utilisez <link rel = « preload »> pour la récupérer plus tôt. Différentes ressources peuvent être préchargées, mais vous avez tout intérêt à vous concentrer sur le préchargement des ressources critiques, tels que les fonts, les médias au-dessus de la ligne de flottaison, les CSS du chemin critique et les JS.
[pastacode lang= »javascript » manual= »%3Clink%20rel%3D%22preload%22%20as%3D%22script%22%20href%3D%22script.js%22%3E%0A%3Clink%20rel%3D%22preload%22%20as%3D%22style%22%20href%3D%22style.css%22%3E%0A%3Clink%20rel%3D%22preload%22%20as%3D%22image%22%20href%3D%22img.png%22%3E%0A%3Clink%20rel%3D%22preload%22%20as%3D%22video%22%20href%3D%22vid.webm%22%20type%3D%22video%2Fwebm%22%3E%0A%3Clink%20rel%3D%22preload%22%20href%3D%22font.woff2%22%20as%3D%22font%22%20type%3D%22font%2Fwoff2%22%20crossorigin%3E » message= » » highlight= » » provider= »manual »/]
Depuis Chrome 73, preloading peut être utilisé avec les images responsive pour en combiner les avantages et accélérer encore le chargement des images.
[pastacode lang= »markup » manual= »%3Clink%0A%20%20rel%3D%22preload%22%0A%20%20as%3D%22image%22%0A%20%20href%3D%22wolf.jpg%22%0A%20%20imagesrcset%3D%22wolf_400px.jpg%20400w%2C%20wolf_800px.jpg%20800w%2C%20wolf_1600px.jpg%201600w%22%0A%20%20imagesizes%3D%2250vw%22%0A%3E » message= » » highlight= » » provider= »manual »/]
Compresser les fichiers texte
Les algorithmes de compression, comme Gzip et Brotli, peuvent réduire considérablement la taille des fichiers texte (HTML, CSS, JavaScript) lors de leur transfert entre le serveur et le navigateur. Gzip est efficacement pris en charge dans tous les navigateurs et Brotli, qui fournit des résultats de compression encore meilleurs, peut être utilisé sur presque tous les navigateurs récents.
La compression de vos ressources réduira leur taille, améliorant ainsi les temps de chargement et par conséquent le LCP.
- Tout d’abord, vérifiez si votre serveur compresse déjà automatiquement les fichiers. La plupart des plateformes d’hébergement, des CDN et des reverse proxies encodent des ressources avec une compression par défaut, ou vous permettent de les configurer facilement.
- Si vous devez modifier votre serveur pour compresser des fichiers, pensez à utiliser Brotli au lieu de gzip car il peut fournir de meilleurs taux de compression (NdT : notre moteur vous permet de bénéficier facilement des avantages de la compression Brotli).
- Une fois que vous avez choisi un algorithme de compression, compressez les ressources à l’avance pendant le processus de génération au lieu de les utiliser à la volée, comme le demande le navigateur. Cela réduit la charge du serveur et évite les délais lors des requêtes, en particulier lors de l’utilisation de taux de compression élevés.
Exemple d’amélioration du LCP : avant et après la compression Brotli
Pour plus de détails sur la compression des ressources, vous pouvez consulter ce guide (en anglais) : Minify and compress network payloads.
L’adaptive serving
Lors du chargement de ressources qui composent le contenu principal d’une page, il peut être efficace de récupérer conditionnellement différentes ressources en fonction de l’appareil de l’utilisateur ou des conditions du réseau. Cela peut être fait en utilisant les API Network Information, Device Memory et HardwareConcurrency.
Si vous disposez de ressources importantes qui sont essentielles pour le rendu initial, vous pouvez utiliser différentes variantes de la même ressource en fonction de la connexion ou du périphérique de l’utilisateur. Par exemple, vous pouvez afficher une image au lieu d’une vidéo pour toute vitesse de connexion inférieure à 4G :
[pastacode lang= »javascript » manual= »if%20(navigator.connection%20%26%26%20navigator.connection.effectiveType)%20%7B%0A%C2%A0if%20(navigator.connection.effectiveType%20%3D%3D%3D%20’4g’)%20%7B%0A%C2%A0%C2%A0%C2%A0%2F%2F%20Load%20video%0A%C2%A0%7D%20else%20%7B%0A%C2%A0%C2%A0%C2%A0%2F%2F%20Load%20image%0A%C2%A0%7D%0A%7D » message= » » highlight= » » provider= »manual »/]
Voici une liste des propriétés que vous pouvez utiliser :
- navigator.connection.effectiveType
- navigator.connection.saveData (activation / désactivation de l’économiseur de données)
- navigator.hardwareConcurrency (CPU)
- navigator.deviceMemory
Pour plus d’informations sur l’adaptive serving, vous pouvez consulter cette ressource (en anglais) : Adaptive serving based on network quality.
Mise en cache des ressources à l’aide d’un Service Worker
Les Service Workers peuvent être utilisés pour de nombreuses tâches, notamment pour servir des réponses HTML plus petites, comme mentionné plus haut. Ils peuvent également être utilisés pour mettre en cache toute ressource statique qui peut être servie au navigateur plutôt qu’à partir du réseau avec des demandes répétées.
La mise en cache préalable des ressources critiques à l’aide d’un Service Worker peut réduire considérablement leurs temps de chargement, en particulier pour les utilisateurs qui rechargent la page web avec une connexion plus faible (ou même hors ligne). Des librairies telles que Workbox peuvent rendre le processus de mise à jour des ressources mises en cache plus facile que de concevoir un Service Worker personnalisé pour gérer cela vous-même.
Vous pouvez consulter cette ressources (en anglais) pour en savoir plus : Network reliability.
Client-side rendering et optimisation du Largest Contentful Paint
De nombreux sites utilisent du JS côté client pour afficher les pages directement dans le navigateur. Les frameworks et les librairies comme React, Angular, et Vue, ont facilité la création de Single Page Applications qui gèrent les différentes facettes d’une page web entièrement côté client plutôt que côté serveur.
Si vous créez un site qui est principalement rendu côté client, vous devez vous méfier de l’effet que cela peut avoir sur le LCP si un grand bundle JavaScript est utilisé. Si des optimisations ne sont pas en place pour l’empêcher, les utilisateurs peuvent ne pas voir ou interagir avec le contenu de la page avant que tout le JavaScript critique ne soit téléchargé et exécuté.
Lors de la création d’un site rendu côté client, tenez compte des optimisations suivantes :
- Réduisez le JavaScript critique
- Utilisez le Server-side rendering
- Utilisez le pre-rendering
Réduire le JavaScript critique
Si le contenu de votre site ne devient visible ou ne peut être actif qu’après le téléchargement d’une certaine quantité de JavaScript, c’est encore plus important de réduire autant que possible la taille de votre bundle. Cela peut être fait grâce aux techniques suivantes :
- Minifier le JavaScript
- Différer le JavaScript inutilisé
- Réduire les polyfills inutilisés
Le Server-side rendering (rendu côté serveur)
La réduction de la quantité de JavaScript doit toujours être une priorité pour les sites qui sont principalement rendus côté client. Cependant, vous devriez également envisager de combiner le rendu côté serveur pour améliorer autant que possible LCP.
Ce concept fonctionne en utilisant le serveur pour rendre l’application en HTML, où le client hydrate ensuite le JavaScript et les données demandées sur le même contenu DOM. Cela peut améliorer LCP en garantissant que le contenu principal de la page est d’abord rendu sur le serveur plutôt que seulement côté client, mais il y a toutefois quelques inconvénients :
- La maintenance de la même application rendue en JavaScript côté serveur et côté client peut augmenter la complexité.
- L’exécution de JavaScript pour rendre un fichier HTML sur le serveur augmentera toujours les temps de réponse du serveur (TTFB) par rapport à la simple diffusion de pages statiques à partir du serveur.
- Une page rendue par le serveur peut sembler interactive, mais elle ne peut répondre à aucun input utilisateur tant que tout le JavaScript côté client n’a pas été exécuté. En bref, cela peut dégrader le Time to Interactive (TTI).
Utiliser le pre-rendering
Le pre-rendering est une technique à part qui est moins complexe que le Server-side rendering et qui permet également d’améliorer le LCP. Un navigateur headless – sans interface utilisateur – , est employé pour générer des fichiers HTML statiques correspondant à chaque route au moment du build. Ces fichiers peuvent ensuite être envoyés avec les bundles JavaScript nécessaires.
Avec le pre-rendering, le Time To Interactive est forcément affecté, mais les temps de réponse serveur ne le sont pas autant qu’avec une solution de rendu côté serveur, qui restitue dynamiquement chaque page uniquement après sa requête.
Exemple d’amélioration du LCP : avant et après pre-rendering
Pour aller plus loin sur les architectures Server-side, vous pouvez consulter cette ressource (en anglais) : Rendering on the web.
Les outils développeur pour optimiser le Largest Contentful Paint
De nombreux outils existent pour mesurer et améliorer le LCP :
- Lighthouse permet de mesurer le LCP (ainsi que PageSpeed Insights) :
- La section Timings de Performance panel dans Chrome DevTools comprend un marqueur LCP et indique l’élément est associé au LCP lorsque vous survolez le Node associé.
- Chrome User Experience Report propose des valeurs de LCP issues de conditions réelles et agrégées pour un site donné.
Vous souhaitez creuser le sujet en vidéo ? Le replay de notre webinaire dédié au LCP est ici :
Au-delà du LCP et des Core Web Vitals,
vous souhaitez aller plus loin sur les indicateurs webperf,
comprendre leur fonctionnement et les améliorer ?
L’article original est publié en anglais sur Web.dev
A lire aussi :