En 2022, un site de comparaison d'hébergeurs m'est arrivé dans la boîte de réception. Grand catalogue, environ 4 000 pages, structure de catégories profondément imbriquées, des liens d'affiliation éparpillés partout, des images héros de la taille de petits continents. Leur Google Search Console était un cauchemar. LCP à 4,2 secondes sur mobile. INP (à l'époque encore appelé FID) limite. Le client avait déjà dépensé 6 000 £ avec une agence précédente qui lui avait collé un CDN et appelé ça un jour.
Ce projet est celui qui a finalement façonné notre façon de penser la performance chez Seahawk pour les sites à fort nombre de pages, les annuaires, les plateformes de listes, les propriétés d'avis d'hébergement comme les builds HostList. Ce qui suit est le playbook réel.
---
Pourquoi les grands sites cassent LCP différemment
Les petits sites ont des problèmes simples. Une image hero, un thème, un plugin qui en fait trop. Réparez ces trois choses et vous êtes sous 2 secondes.
Les gros sites ? C'est un animal complètement différent. L'élément LCP change selon la page où tu te trouves. Une archive de catégories a un candidat LCP différent d'une page de détail produit, qui a un candidat différent de la page d'accueil. La plupart des outils de performance rapportent un score unique. Ce chiffre est un mensonge, c'est une moyenne d'un ensemble sauvagement varié de pages, et corriger la page d'accueil en ignorant les 3 800 pages de listes en dessous, c'est exactement comment les agences se font une mauvaise réputation.
La documentation Core Web Vitals de Google est claire : les données de terrain, ce que les vrais utilisateurs vivent, mesuré dans le rapport Chrome User Experience, c'est ce que Google utilise réellement pour les signaux de classement. Les données de lab de PageSpeed Insights sont directionnelles, pas définitives. J'ai vu des sites scorer 95 sur PSI et avoir quand même un LCP mauvais dans les données CrUX. Ne confonds pas les deux.
Les Trois Vrais Coupables sur les Sites de Listing
Sur chaque gros site que j'ai audité (et j'en ai parcouru des centaines à ce stade), les défaillances LCP remontent presque toujours à trois causes profondes :
- Images héros ou de cartes non optimisées, souvent servies en pleine résolution, format incorrect, pas d'indice
fetchpriority - Scripts tiers bloquant le rendu, traceurs d'affiliation, réseaux publicitaires, widgets de comparaison chargeant avant que le navigateur ne puisse afficher quoi que ce soit
- TTFB gonflant le budget LCP, réponse serveur lente mangeant 600-900ms avant que la page commence même à se charger
Celui-là, c'est celui que les gens sous-estiment. Si ton TTFB est de 700ms, tu as déjà dépensé près de la moitié de ton budget LCP « Bon » avant que le navigateur ait rendu un seul pixel. Le choix d'hébergement et la mise en cache côté serveur ne sont pas des préoccupations DevOps, ce sont des préoccupations SEO.
---
Commencez par le TTFB : C'est d'abord un problème d'hébergement et de mise en cache
Le projet de type HostList dont j'ai parlé plus haut ? La première chose que j'ai faite a été d'exécuter WebPageTest à partir de cinq emplacements géographiques différents. Le TTFB était constamment 680-820ms. Le site était sur un hébergement mutualisé en Virginie. La plupart de leur trafic organique provenait du Royaume-Uni et d'Allemagne.
Je les ai déplacés vers un hébergeur WordPress géré avec des nœuds de périphérie à Londres et Francfort. J'ai configuré la mise en cache de page complète avec des durées de cache de 12 heures sur les pages de liste (les données ne changeaient pas si souvent de toute façon). Le TTFB est tombé à 120-180ms sur les demandes répétées, 280-350ms sur les défauts de cache à première visite. Ce seul changement a réduit d'environ 500ms le LCP avant que je ne touche à une seule image.
Quelques points que je vérifie toujours du côté de l'hébergement:
- La mise en cache full-page fonctionne-t-elle réellement? Vérifiez l'en-tête de réponse
X-Cache. Si elle afficheMISSà chaque requête, votre couche de cache ne fonctionne pas. - Le serveur d'origine est-il géographiquement proche de votre audience principale? Ça semble évident. Vous seriez surpris de la fréquence à laquelle ça ne l'est pas.
- Le keep-alive est-il activé? Certains hébergeurs bon marché désactivent encore les connexions persistantes. Étonnant en 2024, mais ça arrive.
- HTTP/2 ou HTTP/3 sont-ils actifs? Lancez
curl -I --http2 https://yourdomain.comet vérifiez le protocole dans la réponse.
Ne touchez pas à l'optimisation des images tant que vous n'avez pas résolu le TTFB. Optimiser les images sur un serveur lent, c'est comme peindre une maison qui brûle.
---
Le problème LCP Image (Et pourquoi `fetchpriority` change tout)
D'accord. Les images. Sur un site d'annonces avec des mises en page en grille de cartes, l'élément LCP est presque toujours la première image de carte au-dessus du pli, ou la bannière héros. Le navigateur doit la découvrir, la récupérer, la décoder et la rendre. Chacune de ces étapes peut être retardée.
Voici ce que nous avons réellement fait sur le projet HostList, dans cet ordre :
- Conversion de toutes les images de carte en WebP avec la conversion en masse d'Imagify. La taille moyenne des fichiers a diminué de 58 % sans perte de qualité visible aux résolutions de miniature que nous utilisions (280×180px à l'affichage, servis en 2x pour retina).
- Ajout de `fetchpriority="high"` à la première image de carte. Ce seul changement a réduit d'environ 200ms le LCP mesuré dans WebPageTest. Le navigateur arrête de la traiter comme une image lazy ordinaire et la met en file d'attente immédiatement dans le preload scanner.
- Suppression de `loading="lazy"` des deux premières rangées d'images de carte. Le lazy loading est excellent pour les images en bas de page. Sur la première rangée visible, il vous fait activement du tort. Il dit au navigateur de ne pas charger l'image jusqu'à ce qu'elle soit près de la fenêtre d'affichage, ce qu'elle est déjà.
- Ajouté une balise `<link rel="preload">` pour l'image héros dans le `
<head>` sur le modèle de page d'accueil spécifiquement.
Cette séquence a ramené le LCP de la page d'accueil de 3,1s à 1,4s en conditions de lab. Les données de terrain ont suivi dans environ 28 jours (c'est à peu près le temps qu'il faut aux données CrUX pour refléter les changements à grande échelle).
Une remarque sur les images responsives
Si vous servez la même image de 1400px de large à un appareil mobile, vous brûlez de la bande passante et ajoutez du temps de décodage. Utilisez srcset correctement. Je sais que cela semble une conversation de 2016, mais je le vois probablement sur 40 % des sites qui passent chez Seahawk. La fonction WordPress wp_get_attachment_image() génère srcset automatiquement, mais seulement si l'image a été téléchargée à une résolution suffisante et que le thème ne l'a pas supprimée avec add_filter('max_srcset_width', ...).
---
Scripts bloquant le rendu : la taxe des sites d'affiliation
Les sites de comparaison d'hébergement et les plateformes de listes vivent des revenus d'affiliation. Cela signifie des scripts de suivi tiers. Commission Junction, Impact, Awin, des pixel trackers personnalisés, ils s'accumulent. J'ai compté 14 origines de scripts tiers séparées sur un seul site de listes. Chaque one représente une recherche DNS distincte, une connexion TCP et une poignée de main TLS avant qu'un seul octet de ce script ne soit reçu.
La solution n'est pas de supprimer les scripts. Vous ne pouvez pas, les revenus en dépendent. La solution est la séquençage.
Aucun script tiers ne devrait jamais bloquer le rendu initial de l'élément LCP. Point final.
En pratique, cela signifie :
- Déplacer tous les scripts d'affiliation et d'analyse pour les charger après l'événement
DOMContentLoaded, pas dans<head>. - Utiliser les attributs
asyncoudefersur chaque script que tu contrôles. - Pour les scripts que vous ne contrôlez pas (injectés par des gestionnaires de balises), chargez Google Tag Manager lui-même avec
defer. Oui, c'est sûr pour la plupart des cas d'utilisation du suivi d'affiliation, et la documentation de GTM reconnaît elle-même cette approche. - Utiliser un gestionnaire de scripts comme Asset CleanUp Pro ou la fonctionnalité de délai de script de WP Rocket pour différer les tiers non essentiels jusqu'à une interaction utilisateur (premier défilement ou premier clic).
Lors de la reconstruction de HostList, le report des scripts tiers a réduit le Total Blocking Time de 1 840 ms à 290 ms. Le TBT n'est pas directement une Core Web Vital, mais il est fortement corrélé à l'INP, qui l'est.
---
Chargement de polices : le tueur silencieux de LCP dont personne ne parle
Les polices personnalisées provoquent un mode de défaillance spécifique. Le navigateur affiche votre mise en page, atteint l'élément de texte LCP (parfois LCP est un titre, pas une image), puis attend le fichier de police avant de l'afficher. C'est ce qu'on appelle Flash of Invisible Text, et cela retarde le LCP de 200 ms à plus d'une seconde selon la taille du fichier de police et la proximité du serveur.
Deux choses corrigent cela :
- `
font-display: swap` dans votre déclaration@font-face. Le navigateur rend immédiatement avec une police de secours et effectue l'échange quand la police personnalisée se charge. Le candidat LCP s'affiche à temps. - Auto-hébergez vos polices. Google Fonts ajoute une demande cross-origin. L'auto-hébergement avec l'outil google-webfonts-helper vous permet de servir les polices depuis votre propre domaine, éliminant cette connexion supplémentaire.
J'ai converti un grand annuaire hors de Google Fonts en environ 45 minutes en utilisant cet outil. Le LCP s'est amélioré de 180 ms. Pas transformateur seul, mais combiné avec tout le reste, ces marges s'accumulent.
---
Mesurer ce qui compte vraiment sur le terrain
Les données CrUX sont la vérité absolue. Mais elles ne se mettent à jour que mensuellement et seulement pour les URL ayant un trafic suffisant. Pour les grands sites avec des milliers de pages, vous avez besoin de quelque chose de plus granulaire.
J'utilise l'API PageSpeed Insights scriptée sur un échantillon représentatif d'URL, généralement les 100 pages principales par trafic, 50 pages de niveau catégorie, et 20 pages profondes "fines" du catalogue. L'exécution mensuelle donne une distribution de performance appropriée, pas un score ponctuel.
Dans Lighthouse CI (que nous exécutons dans les pipelines CI/CD pour les clients qui ont des cycles de développement), nous définissons des assertions sur :
- LCP ≤ 2,5s en lab (objectif conservateur, car le field a tendance à accuser un retard de 10-15% sur le lab)
- TBT ≤ 300ms
- CLS ≤ 0,1
Mais honnêtement, pour une construction de type HostList où l'objectif est un LCP inférieur à 1,5s, les cibles de lab doivent être plus strictes. Nous définissons LCP ≤ 1,8s dans Lighthouse CI pour ces projets, ce qui produit généralement 1,3-1,5s dans les données de terrain une fois que CrUX rattrape son retard.
---
Tout Assembler : Le Résultat HostList
Après avoir appliqué tout ce qui précède, migration d'hébergement, cache pleine page, conversion de formats d'images, fetchpriority sur les candidats LCP, suppression du lazy-load des lignes au-dessus de la pliure, report des scripts, et auto-hébergement des polices, voici à quoi ressemblaient les chiffres :
- TTFB : 780ms → 160ms (médiane, visiteurs au Royaume-Uni)
- LCP (lab, mobile) : 4,2 s → 1,4 s
- LCP (field, CrUX, 75e percentile) : 3,8 s → 1,6 s (mesuré 60 jours après la migration)
- TBT : 1 840 ms → 290 ms
- CLS : était déjà bon à 0,03, inchangé
Tous les sites ne bénéficieront pas d'une amélioration de 2,8 secondes. Mais presque tous les grands sites d'annonces sur lesquels j'ai travaillé avaient tous ces problèmes simultanément, ce qui signifie que les gains s'accumulent. Corriger une chose et vous gagnez 300 ms. Corriger toutes et vous gagnez 2,5 secondes.
---
FAQ
L'hébergement compte-t-il vraiment autant pour le LCP ?
Oui, probablement plus que n'importe quoi d'autre au départ. Si votre TTFB est au-dessus de 500ms, aucune optimisation d'image ne vous permettra d'atteindre un LCP « Bon ». TTFB est la fondation sur laquelle tout le reste repose. Amenez-le d'abord en dessous de 200ms, puis préoccupez-vous du reste.
Dois-je utiliser un CDN au lieu de migrer d'hébergement ?
Un CDN aide à la livraison des assets statiques et peut réduire le TTFB pour le HTML en page complète mis en cache s'il est configuré correctement. Mais de nombreuses configurations CDN ne cachent que les assets, pas les réponses HTML complètes. Vérifiez si votre CDN sert réellement du HTML mis en cache ou s'il décharge seulement les images. Si c'est ce dernier cas, un meilleur serveur d'origine fera plus pour le LCP.
`fetchpriority="high"` est-il largement supporté maintenant ?
Depuis 2024, oui, c'est supporté dans Chrome, Edge, et Safari (depuis Safari 17.2). Le support de Firefox est arrivé dans Firefox 132. Pour les navigateurs qui ne le supportent pas, c'est ignoré sans danger. Il n'y a aucun inconvénient à l'ajouter à votre élément d'image LCP.
Combien de temps faut-il aux données CrUX pour refléter les améliorations ?
Environ 28 jours à partir du moment où les vrais utilisateurs commencent à expérimenter la version plus rapide du site. CrUX utilise une fenêtre glissante de 28 jours. Donc si vous déployez des changements aujourd'hui, votre score de données terrain ne les reflètera pleinement que dans environ un mois. Ne paniquez pas si PageSpeed Insights affiche toujours « À améliorer » le lendemain de votre sprint d'optimisation.
Quel est le changement au plus fort impact pour un site d'annonces ?
Sur pratiquement tous les projets, c'était le TTFB. Mais le deuxième facteur le plus élevé a régulièrement été la suppression de loading="lazy" des images de carte au-dessus de la ligne de flottaison et l'ajout de fetchpriority="high". Ces deux choses représentent généralement à elles seules 40-60% de l'amélioration totale du LCP. Tout le reste est des gains composés en plus de cette fondation.
---
Le travail de performance sur les gros sites, c'est surtout de la plomberie. Peu glamour, méthodique, et profondément satisfaisant quand vous faites descendre un LCP de 4 secondes à 1,4 secondes et que vous voyez le trafic organique augmenter deux mois plus tard. Il n'y a pas de paramètre magique unique, juste une séquence de décisions spécifiques prises dans le bon ordre.
Rendez le serveur rapide. Ensuite, faites découvrir et charger l'élément LCP tôt. Puis écartez tout le reste de son chemin.
