En 2022, un site de comparaison d'hébergement m'est arrivé dans ma boîte mail. Grand catalogue — environ 4 000 pages, structure de catégories profondément imbriquée, des liens d'affiliation éparpillés partout, des images hero de la taille de petits continents. Leur Google Search Console était un cauchemar. LCP à 4,2 secondes sur mobile. INP (alors encore appelé FID) limite. Le client avait déjà dépensé 6 000 £ auprès d'une agence précédente qui avait jeté un CDN dessus et avait appelé ça un jour.
Ce projet est celui qui a finalement façonné la façon dont nous pensons la performance chez Seahawk pour les sites à fort nombre de pages — sites annuaires, plateformes de listings, propriétés d'avis d'hébergement comme les constructions de style HostList. Ce qui suit est le vrai playbook.Seahawk for high-page-count sites — directory sites, listing platforms, hosting review properties like HostList-style builds. What follows is the actual playbook.
---
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 tout autre animal. L'élément LCP change selon la page sur laquelle vous êtes. Une archive de catégorie a un candidat LCP différent d'une page de détail produit, qui a lui-même un candidat différent de la page d'accueil. La plupart des outils de performance rapportent un seul score. Ce chiffre est un mensonge — c'est une moyenne d'un ensemble de pages extrêmement varié, et corriger la page d'accueil en ignorant les 3 800 pages de listings en dessous est exactement comment les agences se construisent une mauvaise réputation.which page you're on. A category archive has a different LCP candidate than a product detail page, which has a different candidate than the homepage. Most performance tools report a single score. That number is a lie — it's an average of a wildly varied set of pages, and fixing the homepage while ignoring the 3,800 listing pages underneath it is exactly how agencies earn bad reputations.
La documentation Core Web Vitals de Google est claire : les données de terrain — ce que les vrais utilisateurs expérimentent, mesuré dans Chrome User Experience Report — c'est ce que Google utilise réellement pour ses signaux de classement. Les données de laboratoire de PageSpeed Insights sont directionnelles, pas définitives. J'ai vu des sites scorer 95 sur PSI et avoir quand même un LCP Poor dans les données CrUX. Ne confondez pas les deux.Core Web Vitals documentation from Google is clear that field data — what real users experience, measured in Chrome User Experience Report — is what Google actually uses for ranking signals. Lab data from PageSpeed Insights is directional, not definitive. I've seen sites score 95 on PSI and still have Poor LCP in CrSX data. Don't confuse the two.
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 de hero ou de carte non optimisées — souvent servies en pleine résolution, mauvais format, pas de hint fetchpriority — often served at full resolution, wrong format, no
fetchpriorityhint - Scripts tiers qui bloquent le rendu — trackers affiliés, réseaux publicitaires, widgets de comparaison qui se chargent avant que le navigateur puisse afficher quoi que ce soit — affiliate trackers, ad networks, comparison widgets loading before the browser can paint anything
- TTFB qui gonfle le budget LCP — réponse serveur lente qui dévore 600–900ms avant même que la page commence à se charger — slow server response eating 600–900ms before the page even starts loading
C'est ce troisième point que les gens sous-estiment. Si votre TTFB est de 700ms, vous avez déjà dépensé près de la moitié de votre 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 je parlais plus haut? La première chose que j'ai faite, c'est lancer WebPageTest depuis cinq emplacements géographiques différents. Le TTFB était constamment entre 680–820ms. Le site était hébergé sur un serveur partagé en Virginie. La plupart de leur trafic organique provenait du Royaume-Uni et d'Allemagne.WebPageTest from five different geographic locations. TTFB was consistently 680–820ms. The site was on a shared host in Virginia. Most of their organic traffic came from the UK and Germany.
Je les ai déplacés vers un hébergeur WordPress géré avec des nœuds edge à Londres et Francfort. J'ai configuré la mise en cache full-page avec des durées de cache de 12 heures sur les pages de listing (les données ne changeaient pas si souvent de toute façon). Le TTFB est tombé à 120–180ms sur les requêtes répétées, 280–350ms en cas de défaut de cache au premier accès. 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 affiche MISS à chaque requête, votre couche de cache ne fonctionne pas. Check the
X-Cacheresponse header. If it saysMISSon every single request, your caching layer isn't functioning. - 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. This sounds obvious. You'd be surprised how often it's wrong.
- Le keep-alive est-il activé? Certains hébergeurs bon marché désactivent encore les connexions persistantes. Étonnant en 2024, mais ça arrive. Some cheaper hosts still disable persistent connections. Wild in 2024, but it happens.
- HTTP/2 ou HTTP/3 sont-ils actifs? Lancez curl -I --http2 https://yourdomain.com et vérifiez le protocole dans la réponse. Run
curl -I --http2 https://yourdomain.comand check the protocol in the response.
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 de listings avec des mises en page en grille de cartes, l'élément LCP est presque toujours la première image de carte au-dessus de la ligne de flottaison — 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 :
- Converti toutes les images de carte en WebP — en utilisant la conversion en masse d'Imagify. La taille moyenne des fichiers a chuté de 58 % sans perte de qualité visible aux tailles de vignettes de carte que nous utilisions (280×180px affichés, servis en 2x pour rétina). — using Imagify's bulk conversion. Average file size dropped 58% without visible quality loss at the card thumbnail sizes we were using (280×180px display, served at 2x for retina).
- Ajouté `fetchpriority="high"` à la première image de carte — Ce seul changement a réduit d'environ 200ms le LCP mesuré dans WebPageTest. Le navigateur cesse de la traiter comme une image lazy ordinaire et la met en file d'attente immédiatement dans le scanneur de préchargement. — This one change alone knocked ~200ms off measured LCP in WebPageTest. The browser stops treating it like a regular lazy image and queues it immediately in the preload scanner.
- Supprimé `loading="lazy"` des deux premières lignes d'images de carte — Le chargement lazy est excellent pour les images sous la ligne de flottaison. Sur la première ligne visible, il vous fait du tort. Cela indique au navigateur de ne pas récupérer l'image tant qu'elle n'est pas près de la fenêtre — alors qu'elle l'est déjà. — Lazy loading is brilliant for below-fold images. On the first visible row, it actively hurts you. It tells the browser to not fetch the image until it's near the viewport — which it already is.
- Ajouté une balise `<link rel="preload">` pour l'image héros dans le `<head>` sur le modèle de page d'accueil spécifiquement. in the
<head>on the homepage template specifically.
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 gaspillez la bande passante et vous ajoutez du temps de décodage. Utilisez srcset correctement. Je sais que cela semble être une conversation de 2016, mais je le vois toujours sur probablement 40 % des sites qui passent par 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', ...).srcset properly. I know this sounds like a 2016 conversation but I still see it on probably 40% of the sites that come through Seahawk. The WordPress wp_get_attachment_image() function generates srcset automatically — but only if the image was uploaded at sufficient resolution and the theme hasn't suppressed it with 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 d'annuaires vivent grâce aux revenus d'affiliation. Cela signifie des scripts de suivi tiers. Commission Junction, Impact, Awin, des traceurs de pixels personnalisés — ils s'accumulent. J'ai compté 14 origines de scripts tiers distinctes sur un seul site d'annuaire. Chacune représente une recherche DNS distincte, une connexion TCP et une poignée de main TLS avant que le moindre octet de ce script ne soit reçu.
La solution n'est pas de supprimer les scripts. Tu ne peux pas — les revenus en dépendent. La solution, c'est l'ordonnancement.
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>.after the
DOMContentLoadedevent, not in<head>. - Utiliser les attributs async ou defer sur chaque script que tu contrôles.
asyncordeferattributes on every script you control. - Pour les scripts que tu ne contrôles pas (injectés par des gestionnaires de balises), charger 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 elle-même reconnaît cette approche.
defer— yes, this is safe for most affiliate tracking use cases, and GTM's own documentation acknowledges this approach. - 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.is.
---
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 affiche immédiatement dans une police de secours et bascule lorsque la police personnalisée se charge. Le candidat LCP s'affiche à temps.in your@font-facedeclaration — the browser renders in a fallback font immediately and swaps when the custom font loads. LCP candidate gets painted on time.- 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.google-webfonts-helper tool lets you serve fonts from your own domain, cutting that extra connection.
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 sur un échantillon représentatif d'URL — généralement les 100 premières pages par trafic, 50 pages au niveau des catégories, et 20 pages de catalogue "minces" en profondeur. Exécuter cela mensuellement donne une réelle distribution de performance, pas un score unique.PageSpeed Insights API scripted across a representative sample of URLs — typically the top 100 pages by traffic, 50 category-level pages, and 20 "thin" deep-catalogue pages. Running this monthly gives a proper performance distribution, not a single-point score.
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 (cible conservatrice, puisque le field tend à traîner le lab de 10–15%)
- TBT ≤ 300ms
- CLS ≤ 0,1
Mais honnêtement — pour une build de type HostList où l'objectif est un LCP inférieur à 1,5s — les cibles en 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 en données field une fois que CrUX se met à jour.
---
Tout Assembler : Le Résultat HostList
Après avoir parcouru tout ce qui précède — migration d'hébergement, cache pleine page, conversion de format d'image, fetchpriority sur les candidats LCP, suppression du lazy-load des lignes au-dessus du pli, deferral de script, et auto-hébergement de polices — voici à quoi ressemblaient les chiffres :fetchpriority on LCP candidates, lazy-load removal from above-fold rows, script deferral, and font self-hosting — here's what the numbers looked like:
- TTFB : 780ms → 160ms (médiane, visiteurs au Royaume-Uni): 780ms → 160ms (median, UK visitors)
- LCP (lab, mobile) : 4,2 s → 1,4 s: 4.2s → 1.4s
- LCP (field, CrUX, 75e percentile) : 3,8 s → 1,6 s (mesuré 60 jours après la migration): 3.8s → 1.6s (measured 60 days post-migration)
- TBT : 1 840 ms → 290 ms: 1,840ms → 290ms
- CLS : était déjà bon à 0,03, inchangé: was already fine at 0.03, unchanged
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 supérieur à 500 ms, aucune optimisation d'images ne vous permettra d'atteindre un LCP « Bon ». TTFB est la base sur laquelle tout le reste repose. Commencez par le ramener sous 200 ms, puis inquiétez-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 ?
À partir de 2024, oui — c'est supporté dans Chrome, Edge et Safari (depuis Safari 17.2). Le support de Firefox est arrivé avec Firefox 132. Pour les navigateurs qui ne le supportent pas, c'est ignoré sans risque. 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, ça a été le TTFB. Mais le deuxième plus impactant a été de manière constante la suppression de `loading="lazy"` des images de cartes au-dessus de la ligne de flottaison et l'ajout de `fetchpriority="high"`. Ensemble, ces deux choses représentent généralement 40–60 % de l'amélioration totale du LCP. Tout le reste ajoute des gains supplémentaires sur cette fondation.loading="lazy" from above-fold card images and adding fetchpriority="high". Together those two things usually account for 40–60% of the total LCP improvement. Everything else is compounding gains on top of that foundation.
---
Le travail de performance sur les gros sites, c'est surtout de la plomberie. Sans glamour, méthodique, et profondément satisfaisant quand vous faites passer un LCP de 4 secondes à 1,4 seconde et que vous voyez le trafic organique augmenter deux mois plus tard. Il n'y a pas un seul paramètre magique — juste une succession 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.
