Vitesse et Core Web Vitals
La vitesse est un signal mesuré, pas une opinion : Google lit les données Chrome de vrais visiteurs. Ces actions visent les trois métriques qui comptent, et le chemin de rendu qui les produit.
Pourquoi ce module existe
Le bloc le plus important de la liste, parce que les modes de défaillance sont nombreux et que chacun est spécifique.
Module D 30 actions n° 49 à 78 sur 410
-
049
Ré-encoder les photos en AVIF (avifenc --min 20 --max 30) et les visuels d’interface, graphiques et captures en WebP (cwebp -q 80)
- Comment
- Séparez les images : photos d’un côté, visuels à aplats (captures, schémas, logos) de l’autre.
- Photos : avifenc --min 20 --max 30 photo.png photo.avif (ou via sharp/Squoosh), puis une version WebP en repli.
- Captures et graphiques : cwebp -q 80 capture.png -o capture.webp ; gardez le PNG seulement si le WebP dégrade le texte.
- Comparez visuellement à 100 % avant de remplacer : un AVIF trop compressé lisse les textures.
- À éviter
- Encoder un logo ou un schéma en AVIF avec perte : le texte bave
- Remplacer les JPEG sans garder de repli pour les vieux navigateurs
- Réencoder un JPEG déjà très compressé : on empile deux pertes
- Vérifier
- DevTools → Network → filtre Img : les photos arrivent en avif, les captures en webp.
- Comparez le poids total des images de 3 pages avant et après : baisse attendue de 30 à 60 %.
-
050
Servir les images avec <picture>, en AVIF/WebP plus un <source> de repli JPEG/PNG
- Comment
- Générez trois versions de chaque image : AVIF, WebP, JPEG. Utilisez cavif pour l’AVIF, cwebp pour le WebP, et votre export JPEG habituel.
- Dans votre HTML, utilisez plusieurs sources : <picture> <source srcset="image.avif" type="image/avif"> <source srcset="image.webp" type="image/webp"> <img src="image.jpg" alt="..." width="1600" height="900"> </picture>
- Les navigateurs modernes (Chrome, Firefox, Safari 16+) prendront l’AVIF. Les plus anciens retomberont sur le WebP ou le JPEG.
- Sous WordPress, une extension comme ShortPixel ou Imagify. Sous Next.js, le composant next/image avec l’AVIF activé dans la configuration.
- Vérification : ouvrez la page et regardez l’onglet Réseau. La requête d’image doit être en .avif ou .webp.
- À éviter
- Utiliser l’AVIF sans repli (Safari antérieur à 16 et les vieux Android n’afficheront pas l’image)
- Oublier de renseigner width et height (source de CLS)
- Générer un AVIF de qualité inférieure au JPEG d’origine (inutile d’adopter un format moderne s’il rend mal)
- Vérifier
- Ouvrez la page dans les DevTools de Chrome → Réseau. Repérez les requêtes d’images. La colonne de format doit indiquer avif ou webp sur un navigateur moderne.
- Comparez les poids : un AVIF doit peser environ 30 % de moins qu’un WebP de qualité comparable, lui-même environ 30 % plus léger qu’un JPEG.
-
051
Plafonner les images de contenu à 1 600 px de large et 100 Ko ; l’image de couverture à 200 Ko
- Comment
- Pour les images de corps de texte, exportez à 1 600 px de large au maximum. Sur la plupart des écrans de bureau, cela couvre toute la largeur d’un écran 1920 px.
- Pour les images de couverture, exportez à 2 000 px maximum.
- Passez vos images dans un compresseur. Squoosh ou cavif -Q 60 (AVIF) atteignent en général la cible.
- Sur un site statique, automatisez cela dans le pipeline de build. L’optimisation des images doit tourner à chaque build.
- Sous WordPress, ShortPixel ou Imagify avec les bons réglages de qualité.
- À éviter
- Exporter des images de plus de 4 000 px « pour le retina » (les écrans modernes n’ont pas besoin de plus du double de la taille affichée)
- Utiliser du PNG non compressé pour des photos (préférez JPEG/WebP/AVIF)
- Conserver l’original pleine résolution dans le CMS après avoir généré les versions optimisées (gaspillage d’espace disque)
- Vérifier
- Prenez 10 images d’une page. Chacune doit faire moins de 100 Ko (corps de texte) ou 250 Ko (couverture).
- Clic droit sur une image → « Ouvrir dans un nouvel onglet » → vérifiez la largeur et la hauteur réelles en pixels.
-
052
Ajouter srcset et sizes pour que le mobile télécharge les petites variantes
- Comment
- Générez plusieurs tailles de chaque image : 400w, 800w, 1200w, 1600w (et 2000w pour la couverture).
- Utilisez l’attribut srcset sur <img> : <img srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w, image-1600.jpg 1600w" sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px" src="image-1200.jpg" alt="...">
- L’attribut sizes indique au navigateur la largeur d’affichage prévue selon la largeur de la fenêtre. Le navigateur choisit la source la plus proche.
- Sous WordPress, c’est automatique depuis la version 4.4. Sur un site sur mesure, implémentez-le à la main ou via une bibliothèque.
- À éviter
- Utiliser srcset sans sizes (le navigateur suppose 100vw et télécharge la plus grande)
- Se tromper dans les valeurs de sizes (annoncer 50vw quand c’est en réalité 25vw fait télécharger une image inutilement lourde)
- Ne pas générer assez de variantes (quatre tailles suffisent en général)
- Vérifier
- Sur un téléphone de 360 px, ouvrez une page avec des images. La requête doit porter sur la variante 400w ou 800w, pas la 1600w.
- DevTools → Réseau → vérifiez le poids réellement téléchargé pour chaque image.
-
053
Renseigner width et height explicites (ou une aspect-ratio CSS) sur chaque image, iframe et emplacement publicitaire, pour supprimer le CLS
- Comment
- Pour les images : mettez width et height dans le HTML : <img src="..." width="1600" height="900" alt="...">
- Pour les iframes : pareil. <iframe width="640" height="360" src="...">
- Pour les emplacements publicitaires : réservez la place en CSS. .ad-slot { min-height: 250px; }
- Pour les widgets intégrés : réservez la hauteur avant leur chargement.
- En CSS moderne, vous pouvez utiliser aspect-ratio: 16/9 sur un conteneur au lieu de dimensions explicites. Les deux approches conviennent.
- À éviter
- Utiliser width: 100% en CSS sans aspect-ratio sur le conteneur (l’image arrive, le conteneur se redimensionne, la mise en page saute)
- Charger des polices sans size-adjust ni font-display: optional (le texte se recompose quand la police arrive)
- Injecter du contenu au-dessus du contenu existant (une bannière apparaît et la page descend)
- Vérifier
- Lancez PageSpeed Insights. Le « Cumulative Layout Shift » doit être sous 0,1.
- Regardez un chargement bridé en 3G lente. Aucun contenu visible ne doit bouger pendant le rendu.
-
054
Ajouter loading="lazy" à toutes les images et iframes sous la ligne de flottaison ; JAMAIS à l’image LCP
- Comment
- Pour chaque image hors de la fenêtre initiale : <img src="..." loading="lazy" width="..." height="..." alt="...">
- Pour chaque iframe (YouTube, publicité, contenu intégré) : le même attribut.
- Pour l’image LCP (la première grande image, en général la couverture) : n’ajoutez PAS loading="lazy". Le chargement paresseux diffère l’image, donc retarde le LCP.
- Les navigateurs ont leur propre heuristique de chargement paresseux. loading="lazy" la rend explicite et démarre le chargement plus tôt, avant que le visiteur n’arrive dessus.
- À éviter
- Mettre l’image LCP en lazy (l’optimisation se retourne contre vous — le LCP se dégrade)
- Mettre en lazy des images au-dessus de la ligne de flottaison (aucun gain, du contenu visible différé)
- Ne pas mettre en lazy les iframes situées plus bas (coûteux — une vidéo YouTube intégrée pèse plus de 500 Ko)
- Vérifier
- Ouvrez une page longue. L’image LCP doit se charger immédiatement. Les images plus bas doivent se charger au défilement.
- DevTools → Réseau. Filtrez sur les images. Observez lesquelles se chargent et quand.
-
055
Mettre fetchpriority="high" sur l’image LCP et la précharger avec <link rel="preload">
- Comment
- Identifiez votre image LCP. Servez-vous de PageSpeed Insights ou de l’onglet Performance de Chrome. C’est en général l’image de couverture ou la première grande image de contenu.
- Ajoutez un lien de préchargement dans le head : <link rel="preload" as="image" href="/hero.avif" imagesrcset="/hero-400.avif 400w, /hero-800.avif 800w, /hero-1600.avif 1600w" imagesizes="100vw">
- Si vous utilisez srcset et sizes, reprenez-les dans le preload. Le navigateur s’en sert pour choisir la bonne variante.
- Ne préchargez pas plus d’une image. Précharger plusieurs images dilue la priorité et peut dégrader les performances.
- À éviter
- Précharger la mauvaise image (c’est l’image LCP qu’il faut précharger, pas la plus visible à vos yeux)
- Précharger plusieurs images (le signal de priorité s’annule)
- Précharger sans srcset (vous imposez une taille unique, même sur petit écran)
- Vérifier
- DevTools → Réseau. L’image préchargée doit apparaître avec la priorité « High » dans la cascade réseau.
- Relancez PageSpeed Insights. Le LCP doit s’améliorer.
-
056
Héberger les polices soi-même (WOFF2), les sous-ensembler aux glyphes utilisés, mettre font-display: swap et précharger la police principale
- Comment
- Téléchargez les fichiers WOFF2 des graisses réellement utilisées et servez-les depuis votre domaine (fini la connexion à fonts.googleapis.com).
- Sous-ensemblez-les aux caractères de vos langues : pyftsubset police.woff2 --unicodes=U+0000-00FF,U+0131,U+0152-0153,U+2013-2026 --flavor=woff2.
- Déclarez @font-face avec font-display: swap.
- Préchargez la seule police du texte visible au premier écran : <link rel="preload" href="/fonts/texte.woff2" as="font" type="font/woff2" crossorigin>.
- À éviter
- Précharger 4 ou 5 polices : elles concurrencent l’image principale
- Oublier crossorigin sur le preload : la police est téléchargée deux fois
- Sous-ensembler trop court et perdre les accents ou les guillemets français
- Vérifier
- DevTools → Network → Font : chaque police vient de votre domaine, en woff2, sous ~30 Ko pour une graisse latine.
- Chargez une page avec du texte accentué (é, à, œ, « ») : aucun caractère en police de repli.
-
057
Minifier le HTML, le CSS et le JS (à l’étape de build : esbuild, terser, cssnano, ou un module serveur)
- Comment
- Ajoutez la minification à l’étape de build : esbuild --minify pour le JS, cssnano (via PostCSS) ou lightningcss --minify pour le CSS, html-minifier-terser pour le HTML.
- Sur WordPress, utilisez un plugin de cache qui minifie (WP Rocket, LiteSpeed Cache), une option à la fois.
- Générez des source maps pour déboguer sans servir le code non minifié.
- Retestez le site entier après activation : la minification casse parfois un script mal écrit.
- À éviter
- Minifier à la volée à chaque requête sans cache : le serveur ralentit
- Activer minification et concaténation de plusieurs plugins en même temps
- Minifier le HTML en supprimant des espaces significatifs entre éléments inline
- Vérifier
- DevTools → Sources : les fichiers CSS et JS servis sont sur une ligne.
- PageSpeed Insights : les recommandations « Réduire la taille du CSS / du JavaScript » ne listent plus vos fichiers.
-
058
Inliner le CSS critique au-dessus de la ligne de flottaison ; charger le reste en media/async
- Comment
- Extrayez le CSS nécessaire au premier écran de chaque gabarit avec critical (npm) ou l’option intégrée de votre outil de build.
- Placez-le dans un <style> dans le <head> (visez moins de ~14 Ko compressé).
- Chargez la feuille complète sans bloquer : <link rel="preload" href="/app.css" as="style" onload="this.rel='stylesheet'"> avec un <noscript> de repli.
- Régénérez le CSS critique à chaque changement de gabarit.
- À éviter
- Inliner toute la feuille de style dans chaque page : le HTML grossit et rien n’est mis en cache
- Un CSS critique périmé : la page saute quand la vraie feuille arrive (CLS)
- Oublier le <noscript>
- Vérifier
- PageSpeed Insights : « Éliminer les ressources qui bloquent le rendu » ne cite plus la feuille principale.
- Chargez la page en 3G simulée : le premier écran s’affiche mis en forme, sans flash de contenu brut.
-
059
Passer tout le JavaScript non critique en defer ou async ; sortir les <script> du chemin de rendu
- Comment
- Listez les <script> du <head> et du corps.
- Scripts qui ont besoin du DOM mais pas d’être exécutés tôt : ajoutez defer (ordre conservé).
- Scripts indépendants (mesure d’audience, chat) : async, ou chargement après l’événement load.
- Déplacez les scripts en ligne qui manipulent la page après le contenu ou transformez-les en modules (type="module" est différé par défaut).
- À éviter
- Mettre async sur des scripts qui dépendent l’un de l’autre : ordre d’exécution aléatoire
- Différer un script qui affiche le contenu principal : le LCP recule
- Laisser jQuery bloquant dans le <head> « parce qu’un plugin en a besoin »
- Vérifier
- PageSpeed Insights → Diagnostics : aucun script tiers dans « ressources qui bloquent le rendu ».
- DevTools → Performance : aucun script ne s’exécute avant le premier affichage, hormis le strict nécessaire.
-
060
Faire du tree-shaking et du découpage de code ; retirer les bibliothèques inutilisées et les polyfills en double
- Comment
- Analysez le bundle : npx vite-bundle-visualizer, webpack-bundle-analyzer, ou source-map-explorer.
- Remplacez les imports complets par des imports ciblés (import debounce from 'lodash-es/debounce').
- Découpez par route avec import() dynamique : chaque page ne charge que son code.
- Ciblez les navigateurs modernes (browserslist) pour ne plus embarquer de polyfills inutiles ; supprimez les dépendances qui n’apparaissent plus dans le code.
- À éviter
- Importer toute une bibliothèque pour une fonction
- Charger Moment.js et date-fns en même temps
- Découper en tant de morceaux que les allers-retours réseau coûtent plus que le gain
- Vérifier
- DevTools → Coverage sur la page d’accueil : la part de JS inutilisé doit baisser nettement.
- Comparez la taille du bundle principal (gzip) avant/après dans le rapport de build.
-
061
Purger le CSS inutilisé (PurgeCSS, UnoCSS) gabarit par gabarit
- Comment
- Générez la liste des classes réellement utilisées à partir des gabarits : PurgeCSS avec content: ['./templates/**/*.html', './src/**/*.js'], ou Tailwind/UnoCSS qui ne produisent que ce qui est utilisé.
- Mettez en liste d’exceptions (safelist) les classes ajoutées dynamiquement par JavaScript.
- Produisez une feuille par gabarit si les pages diffèrent beaucoup.
- Testez chaque type de page après la purge, états interactifs compris (menu ouvert, erreurs de formulaire).
- À éviter
- Purger une classe ajoutée par JavaScript (menu mobile, modale) : l’interface casse sans erreur visible
- Purger le CSS d’un plugin qui génère son HTML côté serveur
- Ne tester que la page d’accueil
- Vérifier
- DevTools → Coverage : CSS inutilisé sous ~20 % sur les pages principales.
- Parcourez chaque gabarit et ouvrez menus, formulaires en erreur et modales : aucun élément sans style.
-
062
Activer la compression Brotli (avec Gzip en repli) sur les ressources texte
- Comment
- Vérifiez ce que le serveur renvoie : curl -sI -H 'Accept-Encoding: br, gzip' https://votresite.com/ | grep -i content-encoding.
- Nginx : module brotli (brotli on; brotli_types text/css application/javascript image/svg+xml application/json;) avec gzip on; en repli.
- Apache : mod_brotli (AddOutputFilterByType BROTLI_COMPRESS text/html text/css application/javascript).
- Pour les fichiers statiques, précompressez au build (.br et .gz) et servez-les directement.
- À éviter
- Compresser les images JPEG/PNG/AVIF : aucun gain, du CPU perdu
- Oublier les types SVG et JSON
- Activer Brotli niveau 11 à la volée : trop lent en dynamique (gardez 11 pour la précompression)
- Vérifier
- curl avec Accept-Encoding: br sur le HTML, un CSS et un JS : content-encoding: br.
- DevTools → Network : la colonne Size montre un transfert nettement inférieur à la taille réelle.
-
063
Poser Cache-Control: public, max-age=31536000, immutable sur les ressources statiques versionnées
- Comment
- Assurez-vous que les fichiers statiques ont un nom versionné (app.3f9a1c.css) ou un paramètre de version qui change à chaque modification.
- Sur ces fichiers : Cache-Control: public, max-age=31536000, immutable.
- Sur le HTML : Cache-Control: no-cache (ou un max-age court) pour que la nouvelle version soit prise.
- Nginx : location ~* \.[0-9a-f]{8}\.(css|js|woff2|avif|webp)$ { add_header Cache-Control "public, max-age=31536000, immutable"; }
- À éviter
- Mettre immutable sur des fichiers non versionnés : les visiteurs gardent l’ancienne version un an
- Mettre un cache long sur le HTML
- Versionner avec la date du build : tout est invalidé à chaque déploiement
- Vérifier
- curl -I sur un CSS versionné : public, max-age=31536000, immutable.
- Rechargez une page (pas en forcé) : DevTools affiche « (memory cache) » ou « (disk cache) » pour les ressources statiques.
-
064
Servir toutes les ressources statiques (images, CSS, JS, polices) depuis un CDN en HTTP/2 ou HTTP/3
- Comment
- Mesurez d’abord le temps de téléchargement des ressources depuis les pays de vos visiteurs (WebPageTest, plusieurs emplacements).
- Placez les ressources statiques derrière un CDN (Cloudflare, Bunny, Fastly), sur le même domaine si possible pour éviter une connexion de plus.
- Vérifiez que le CDN parle HTTP/2 ou HTTP/3 et respecte vos en-têtes de cache.
- Purgez le cache du CDN à chaque déploiement, ou comptez sur les noms versionnés.
- À éviter
- Mettre les ressources sur un sous-domaine CDN séparé sans preconnect : une connexion TLS de plus
- Un CDN qui ignore vos Cache-Control et met en cache le HTML dynamique
- Tester seulement depuis le pays où se trouve le serveur
- Vérifier
- DevTools → Network → colonne Protocol : h2 ou h3 sur les ressources.
- En-têtes de réponse : un indicateur de cache du CDN (cf-cache-status: HIT, x-cache: HIT) sur les fichiers statiques.
-
065
Ajouter <link rel="preconnect"> et dns-prefetch pour les origines tierces critiques
- Comment
- Listez les origines tierces contactées au premier écran (DevTools → Network → Domain) : CDN d’images, API, polices externes.
- Pour les 2 ou 3 origines indispensables tôt : <link rel="preconnect" href="https://cdn.exemple.com" crossorigin>.
- Pour les origines utiles plus tard : <link rel="dns-prefetch" href="https://analytics.exemple.com">.
- Retirez les preconnect vers des origines qui ne servent plus.
- À éviter
- Mettre preconnect vers 10 origines : chaque connexion ouverte coûte
- Oublier crossorigin pour les polices (la connexion préouverte n’est pas réutilisée)
- Preconnect vers une origine chargée seulement après une interaction
- Vérifier
- DevTools → Network → Timing d’une requête vers l’origine : les phases DNS, Connexion et SSL sont à 0 (déjà faites).
- Lighthouse : « Préconnecter aux origines requises » ne propose plus d’origine.
-
066
Charger en différé, ou derrière une façade, les intégrations tierces (YouTube, chat, cartes) jusqu’à l’interaction
- Comment
- Remplacez l’iframe YouTube par une façade : une vignette et un bouton lecture qui chargent l’iframe au clic (lite-youtube-embed).
- Pour le chat, affichez un bouton statique et chargez le script du widget au clic ou après quelques secondes d’inactivité.
- Pour les cartes, une image statique de la carte avec un lien, et la carte interactive au clic.
- Ajoutez loading="lazy" aux iframes qui restent sous la ligne de flottaison.
- À éviter
- Charger 3 iframes YouTube complètes dans un article : plusieurs centaines de Ko de JavaScript avant toute lecture
- Une façade sans texte accessible sur le bouton
- Charger le widget de chat sur toutes les pages, y compris le blog
- Vérifier
- DevTools → Network au chargement : aucune requête vers youtube.com, le widget de chat ou Google Maps avant interaction.
- Lighthouse : « Chargement différé des ressources tierces avec des façades » ne signale plus rien.
-
067
Auditer et supprimer ou limiter les scripts lourds de gestion de tags et de mesure d’audience qui bloquent le thread principal
- Comment
- Listez tous les scripts tiers et leur coût (Lighthouse → « Réduire l’impact du code tiers »).
- Dans le gestionnaire de balises, supprimez les balises mortes (anciennes campagnes, outils résiliés) et les doublons (deux fois le même pixel).
- Déclenchez les balises non essentielles après le chargement de la page ou après consentement.
- Envisagez le suivi côté serveur pour les pixels publicitaires lourds.
- À éviter
- Garder des balises d’une campagne terminée depuis un an
- Charger deux outils d’enregistrement de sessions en même temps
- Tout déclencher sur « All Pages - Page View » au plus tôt
- Vérifier
- Lighthouse → Temps de blocage total : baisse après nettoyage.
- DevTools → Performance → onglet Bottom-Up groupé par domaine : le temps d’exécution des domaines tiers diminue.
-
068
Descendre le TTFB sous 200 ms par le cache serveur, le cache à la périphérie ou la génération statique
- Comment
- Mesurez le TTFB sur plusieurs pages (DevTools → Network → Timing « Waiting for server response », ou WebPageTest).
- Pages qui changent peu : générez-les en statique ou mettez-les en cache complet (cache de page du CMS, Varnish, cache du CDN).
- Pages dynamiques : cache objet (Redis) pour les requêtes lourdes, index de base de données, suppression des requêtes répétées.
- Rapprochez la réponse des visiteurs avec un cache à la périphérie.
- À éviter
- Mesurer le TTFB une seule fois depuis le même datacenter que le serveur
- Mettre en cache des pages personnalisées (panier, compte)
- Accuser l’hébergeur avant d’avoir profilé les requêtes lentes
- Vérifier
- WebPageTest depuis 3 emplacements : TTFB médian sous 200 ms sur les pages en cache.
- Search Console → Paramètres → Statistiques sur l’exploration : le temps de réponse moyen baisse.
-
069
Obtenir un LCP sous 2,5 s (terrain, 75e centile) — à mesurer dans CrUX ou PageSpeed Insights, pas seulement en laboratoire
- Comment
- Récupérez les données terrain : PageSpeed Insights (section « Découvrez ce que vivent vos utilisateurs ») ou Search Console → Signaux web essentiels.
- Identifiez l’élément LCP de chaque gabarit (Lighthouse → Largest Contentful Paint element).
- Si c’est une image : servez-la en AVIF/WebP à la bonne taille, fetchpriority="high", jamais en lazy.
- Si c’est du texte : réduisez le TTFB, le CSS bloquant et le délai d’affichage des polices.
- À éviter
- Optimiser le score Lighthouse de laboratoire et ignorer les données terrain
- Une image LCP injectée par JavaScript ou en arrière-plan CSS : découverte tard
- Un slider en haut de page dont la première image arrive après le script
- Vérifier
- PageSpeed Insights : LCP terrain au 75e centile sous 2,5 s pour la page et pour l’origine.
- Search Console → Signaux web essentiels : les URLs « LCP trop long » passent en « Bonnes » après la période de 28 jours.
-
070
Obtenir un CLS sous 0,1 — réserver la place des polices, des images, des publicités et des bandeaux injectés
- Comment
- Mettez width et height (ou aspect-ratio) sur toutes les images, vidéos et iframes.
- Réservez la hauteur des emplacements publicitaires et des blocs injectés (min-height).
- Pour les polices, choisissez un repli aux métriques proches ou utilisez size-adjust dans @font-face.
- Affichez les bandeaux (cookies, promotions) en superposition fixe plutôt qu’en insertion qui pousse le contenu.
- À éviter
- Insérer un bandeau en haut de page après chargement : tout le contenu descend
- Des emplacements publicitaires sans taille réservée
- Animer top ou height au lieu de transform
- Vérifier
- DevTools → Performance → Layout Shifts : identifiez chaque décalage restant et son élément.
- PageSpeed Insights : CLS terrain au 75e centile sous 0,1.
-
071
Obtenir un INP sous 200 ms — découper les tâches longues, temporiser les gestionnaires d’événements, éviter le JavaScript lourd à l’interaction
- Comment
- Repérez les interactions lentes : Web Vitals Chrome extension en naviguant, ou le rapport INP de PageSpeed Insights (données terrain).
- DevTools → Performance, enregistrez un clic lent : trouvez les tâches longues (plus de 50 ms) dans le gestionnaire d’événements.
- Découpez-les : donnez la main au navigateur avec await scheduler.yield() (ou setTimeout), affichez d’abord un retour visuel, faites le calcul ensuite.
- Temporisez les gestionnaires de saisie et de défilement (debounce, requestAnimationFrame).
- À éviter
- Recalculer tout un filtre de 2 000 produits à chaque frappe
- Un gestionnaire de clic qui force plusieurs recalculs de mise en page (lecture/écriture alternées)
- Hydrater toute la page avant de répondre au premier clic
- Vérifier
- PageSpeed Insights : INP terrain au 75e centile sous 200 ms.
- DevTools → Performance → Interactions : les interactions clés restent sous 200 ms en CPU ralenti ×4.
-
072
Éliminer les ressources bloquant le rendu signalées dans les « Opportunités » de PageSpeed Insights
- Comment
- Lancez PageSpeed Insights et ouvrez « Éliminer les ressources qui bloquent le rendu » : relevez chaque fichier et son coût.
- CSS : inlinez le critique et chargez le reste sans bloquer ; supprimez les feuilles inutilisées sur ce gabarit.
- JavaScript : defer ou async, ou suppression.
- Polices externes : auto-hébergez-les ou préconnectez et utilisez font-display: swap.
- À éviter
- Différer le CSS principal sans CSS critique : la page s’affiche sans style puis saute
- Traiter l’avertissement sur une seule page et pas sur les gabarits
- Supprimer un script bloquant qui est en réalité nécessaire au contenu
- Vérifier
- Relancez PageSpeed Insights sur chaque gabarit : l’opportunité n’apparaît plus ou ne liste plus que des fichiers minimes.
- Le First Contentful Paint de laboratoire baisse.
-
073
Ajouter des indices de ressources (preload pour l’image de couverture, prefetch pour la page suivante probable)
- Comment
- Préchargez l’image principale du premier écran si elle n’est pas découverte tout de suite dans le HTML : <link rel="preload" as="image" href="/hero.avif" imagesrcset="..." imagesizes="100vw" fetchpriority="high">.
- Pour la page suivante probable (étape 2 d’un tunnel), <link rel="prefetch" href="/etape-2/">, ou l’API Speculation Rules pour le préchargement complet.
- Limitez-vous à une ou deux ressources par page.
- Retirez les indices devenus inutiles quand le gabarit change.
- À éviter
- Précharger une image qui n’est pas affichée sur mobile : téléchargement inutile
- Précharger 5 ressources : plus rien n’est prioritaire
- Précharger une image sans imagesrcset : le navigateur télécharge la mauvaise taille
- Vérifier
- DevTools → Network : l’image préchargée part dans les toutes premières requêtes, avec la priorité High, et n’est téléchargée qu’une fois.
- Console : aucun avertissement « preloaded but not used ».
-
074
Compresser et initialiser tardivement un DOM plus lourd que la moyenne (viser moins de 1 500 nœuds) ; aplatir les imbrications profondes
- Comment
- Comptez les nœuds : dans la console, document.querySelectorAll('*').length ; Lighthouse → « Éviter une taille excessive du DOM ».
- Supprimez les enveloppes inutiles (div dans div produits par les constructeurs de pages).
- Ne rendez pas d’avance ce qui n’est pas visible : onglets, méga-menus, longues listes à charger au besoin ou via content-visibility: auto.
- Paginez ou virtualisez les listes de plusieurs centaines d’éléments.
- À éviter
- Un constructeur de page qui produit 8 niveaux de div par bloc
- Rendre en entier un méga-menu de 400 liens et le cacher en CSS
- Cacher du contenu important au crawl en le chargeant seulement au clic
- Vérifier
- Lighthouse : nombre total d’éléments du DOM sous ~1 500, profondeur maximale sous ~32.
- DevTools → Performance : le temps de « Recalculate Style » et « Layout » baisse.
-
075
Activer le format et la qualité automatiques du CDN d’images s’il en propose (servir de l’AVIF aux navigateurs compatibles)
- Comment
- Vérifiez si votre CDN ou hébergeur d’images propose la négociation de format : Cloudflare Polish ou Images, Cloudinary f_auto,q_auto, imgix auto=format,compress.
- Activez-la : le service lit l’en-tête Accept et renvoie AVIF ou WebP aux navigateurs compatibles.
- Assurez-vous que le cache varie selon le format (Vary: Accept) pour ne pas servir de l’AVIF à un navigateur qui ne le lit pas.
- Gardez l’image d’origine en haute qualité : le service ne sait pas recréer un détail perdu.
- À éviter
- Activer l’auto-format sur des images déjà en AVIF mal compressées
- Un cache CDN sans Vary: Accept
- Des URLs d’images signées qui empêchent la transformation
- Vérifier
- Ouvrez une image dans Chrome puis dans un navigateur sans AVIF : le Content-Type diffère (image/avif vs image/jpeg) pour la même URL.
- Poids des images d’une page type : baisse mesurée dans DevTools.
-
076
Mettre en cache l’API et le HTML à la périphérie ; utiliser stale-while-revalidate pour les pages dynamiques mais stables
- Comment
- Identifiez les pages dynamiques mais identiques pour tous les visiteurs (catégories, articles, pages produit sans prix personnalisé).
- Mettez-les en cache à la périphérie avec Cache-Control: public, s-maxage=300, stale-while-revalidate=86400.
- Purgez le cache par URL ou par tag lors d’une modification dans le CMS.
- Excluez explicitement les pages et API liées à la session (panier, compte, paiement).
- À éviter
- Mettre en cache une page qui contient le prénom ou le panier du visiteur
- Un s-maxage d’un jour sans purge : les prix ou stocks affichés sont faux
- Oublier que les cookies de session désactivent souvent le cache CDN
- Vérifier
- curl -I deux fois sur la même page : la seconde réponse indique un HIT et un en-tête age.
- Modifiez un contenu dans le CMS : il apparaît en ligne après la purge, sans attendre l’expiration.
-
077
Surveiller chaque mois les signaux web essentiels dans la Search Console et dans PageSpeed Insights ; corriger les régressions
- Comment
- Planifiez un contrôle mensuel : Search Console → Signaux web essentiels (mobile et ordinateur), groupes d’URLs « Médiocres » et « À améliorer ».
- Pour chaque groupe, ouvrez une URL exemple dans PageSpeed Insights et notez la métrique en défaut.
- Reliez la dégradation à un changement daté (nouveau plugin, nouveau script, nouveau gabarit).
- Notez les valeurs dans un tableau pour voir les tendances d’un mois à l’autre.
- À éviter
- Regarder uniquement le score Lighthouse de laboratoire
- Réagir à une variation d’un jour : les données terrain sont glissantes sur 28 jours
- Corriger sur une page sans corriger le gabarit commun
- Vérifier
- Votre tableau mensuel montre LCP, INP et CLS terrain par gabarit, avec la date de chaque correctif.
- Search Console : après un correctif, cliquez « Valider la correction » et suivez la validation jusqu’au bout.
-
078
Supprimer les éléments à chargement tardif qui décalent la mise en page (bandeaux cookies, blocs « à lire aussi », publicités injectées automatiquement)
- Comment
- Chargez chaque gabarit en enregistrant les décalages (DevTools → Performance, cochez Web Vitals) et listez les éléments qui bougent.
- Bandeau cookies : en position fixe par-dessus le contenu, pas inséré en haut du flux.
- Blocs « à lire aussi » et publicités : emplacement réservé à hauteur fixe dès le HTML.
- Bandeaux promotionnels : rendus côté serveur dans le HTML initial plutôt qu’injectés après chargement.
- À éviter
- Un bandeau de consentement qui pousse toute la page vers le bas à l’apparition
- Des recommandations chargées en JavaScript au milieu de l’article
- Un bandeau d’application qui s’insère après 2 secondes
- Vérifier
- DevTools → Performance → Layout Shifts : aucun décalage causé par ces éléments.
- PageSpeed Insights → CLS terrain des gabarits concernés sous 0,1 après 28 jours.
Continuer
Module suivant
← Module C / 16 actions
Architecture et maillage interne
Les liens internes sont le seul facteur de classement que vous contrôlez entièrement. Ils disent à Google quelles pages comptent, et ils transportent…
Module E / 9 actions →
Mobile
Google indexe la version mobile de votre site. Si du contenu, des liens ou des données structurées n’existent que sur le desktop, ils n’existent…