Page Speed : optimisation complète du chargement de votre site web
Comment distinguer les problèmes de réponse serveur, de chargement, de rendu et d’interaction, puis valider les améliorations avec des données terrain et de laboratoire.
Page Speed est l’un des investissements les plus rentables, à la fois pour le SEO et pour la conversion. Amazon a calculé que chaque tranche de 100 ms de latence supplémentaire coûte 1 % des ventes. Google utilise la vitesse comme critère de classement sur ordinateur depuis 2010, sur mobile depuis 2018, et a introduit en 2021 les Core Web Vitals comme signal direct de Page Experience.
Qu’est-ce que Page Speed et comment on le mesure
Page Speed n’est pas un chiffre unique : c’est un ensemble de métriques, chacune mesurant un aspect différent de l’expérience de chargement. Google PageSpeed Insights combine les données de laboratoire (Lighthouse) et les données terrain des utilisateurs réels (Chrome User Experience Report). Le score final de 0 à 100 est une somme pondérée de plusieurs métriques : il ne doit pas servir de seul objectif d’optimisation.
Pour le SEO, ce sont les données terrain (CrUX) qui comptent : Google utilise le 75e percentile des utilisateurs réels de Chrome pour évaluer les Core Web Vitals. Lighthouse aide à diagnostiquer les problèmes, mais il n’alimente pas directement l’algorithme de classement.
Métriques clés de vitesse
Chaque métrique porte sur un aspect précis de l’expérience utilisateur. Comprendre leurs différences est la base d’un bon diagnostic.
| Métrique | Ce qu’elle mesure | Bonne valeur | Impact sur le classement |
|---|---|---|---|
| TTFB (Time to First Byte) | Délai avant le premier octet de HTML renvoyé par le serveur | < 800 ms | Indirect (via le LCP) |
| FCP (First Contentful Paint) | Premier pixel de contenu affiché à l’écran | < 1,8 s | Lighthouse, pas un facteur CrUX |
| LCP (Largest Contentful Paint) | Affichage du contenu principal pour l’utilisateur | < 2,5 s | Oui (Core Web Vitals) |
| INP (Interaction to Next Paint) | Réactivité aux interactions de l’utilisateur | < 200 ms | Oui (Core Web Vitals, remplace le FID) |
| CLS (Cumulative Layout Shift) | Stabilité de la mise en page : à quel point les éléments sautent | < 0,1 | Oui (Core Web Vitals) |
| TBT (Total Blocking Time) | Durée totale de blocage du thread principal par le JS | < 200 ms | Proxy de laboratoire pour l’INP |
Partent avant 3 s
Utilisateurs mobiles qui abandonnent une page dont le chargement dépasse 3 secondes
Conversion par seconde
Chaque seconde de latence réduit la conversion de 1 à 3 % en moyenne
Percentile CrUX
Google évalue les Core Web Vitals au 75e percentile des utilisateurs réels
Fenêtre CrUX
Période glissante sur laquelle les données sont collectées pour évaluer le site
Diagnostic : par où commencer l’optimisation
Optimiser à l’aveugle fait perdre du temps. L’ordre correct : mesurer d’abord, identifier le goulot d’étranglement, le corriger, puis mesurer à nouveau.
- Ouvrez PageSpeed Insights et testez 5 à 10 pages clés : accueil, catégories, fiches produits, pages d’atterrissage. Regardez les données terrain (Field Data), pas seulement le score Lighthouse.
- Dans la Google Search Console, ouvrez le rapport Core Web Vitals : il indique quelles URL ont une note « Poor » ou « Needs improvement » pour le LCP, l’INP et le CLS, à partir des données réelles des utilisateurs.
- Lancez WebPageTest pour une analyse approfondie : waterfall de chargement, filmstrip, TTFB, impact du CDN. Choisissez la région de test la plus proche de votre audience principale.
- Utilisez Chrome DevTools → Performance et enregistrez un chargement de page. Le flame chart montre quel script occupe le thread principal et bloque le rendu.
- Vérifiez l’onglet Coverage (DevTools → Coverage) : le CSS et le JS inutilisés sont des candidats directs à la suppression ou au chargement différé.
PageSpeed Insights
L’outil gratuit de Google. Affiche les données de laboratoire (Lighthouse) et les données terrain (CrUX). Fournit une liste de recommandations précises avec une estimation du temps gagné. Le meilleur point de départ pour un premier audit.
WebPageTest
Waterfall détaillé, filmstrip, tests depuis plusieurs localisations, comparaison de versions. Montre l’impact du CDN, du DNS et de la négociation SSL. Indispensable pour diagnostiquer finement le TTFB.
Google Search Console
Données CrUX réelles regroupées par groupes d’URL. Montre l’évolution des métriques dans le temps : le meilleur outil pour suivre les gains après le déploiement des optimisations.
Chrome DevTools
Les onglets Performance Profiler et Coverage permettent de trouver le script ou le CSS qui bloque le rendu. Le flame chart révèle les Long Tasks (> 50 ms) dans le thread principal.
Optimisation du serveur et du TTFB
Le TTFB (Time to First Byte) conditionne toute la vitesse. Si le serveur répond lentement, chaque optimisation suivante se heurte à un plafond artificiel. Objectif : TTFB < 200 ms pour les environnements avec CDN, < 400 ms pour les serveurs dynamiques.
Hébergement et infrastructure
- Choix de l’hébergement
- Un hébergement mutualisé, dont les ressources sont partagées entre des milliers de sites, limite physiquement le TTFB. Un VPS ou un serveur dédié avec Nginx ou Caddy et un cache bien configuré donne un TTFB de 20 à 80 ms pour les contenus statiques.
- CDN (Content Delivery Network)
- Cloudflare, BunnyCDN, Fastly : c’est le nœud edge le plus proche qui répond à la place de votre serveur d’origine. Pour les contenus statiques ou mis en cache, le TTFB descend à 10 à 50 ms. Pour les contenus dynamiques, tout dépend de la configuration du cache en edge.
- HTTP/2 et HTTP/3 (QUIC)
- HTTP/2 supprime le head-of-line blocking et gère le multiplexage. HTTP/3, basé sur QUIC, accélère encore l’établissement de la connexion (0-RTT) et résiste mieux à la perte de paquets sur les réseaux mobiles.
- Géolocalisation du serveur
- La distance physique entre l’utilisateur et le serveur ajoute environ 1 ms par tranche de 100 km (aller-retour). Pour une audience majoritairement européenne, un serveur à Francfort ou à Amsterdam est nettement plus rapide qu’un serveur US-East.
Compression et encodage
- Activez Brotli (br) : il économise 15 à 25 % par rapport à gzip, pour une vitesse de décompression comparable. Il est pris en charge par tous les navigateurs modernes.
- Gardez gzip comme solution de repli pour les anciens clients. Minimum : niveau de compression 6.
- Activez la compression pour le HTML, le CSS, le JS, le JSON, le XML et le SVG. Les images et les fichiers binaires sont déjà compressés : leur appliquer gzip ne sert à rien.
- Utilisez l’en-tête Vary: Accept-Encoding pour que le CDN stocke des versions distinctes selon les clients.
Cache côté serveur
Les pages dynamiques (PHP, Node.js, Python) interrogent la base de données à chaque requête. Un cache permet de servir le HTML déjà prêt, sans nouveau calcul.
- Cache de page complet : Nginx FastCGI Cache, Varnish, Redis. Ils stockent le HTML prêt et le servent sans solliciter l’application.
- Cache objet : Redis ou Memcached pour mettre en cache les résultats de requêtes en base, les sessions et les données calculées.
- Règles d’invalidation : le cache doit être purgé à chaque modification du contenu (webhook du CMS, expiration par TTL).
- Stale-while-revalidate : servir immédiatement l’ancien cache et le régénérer en arrière-plan. Les utilisateurs n’attendent pas la régénération.
Optimisation des ressources : images, polices, CSS
Images
Les images sont en général la catégorie la plus lourde du poids d’une page. Une bonne optimisation fait gagner 30 à 70 % de trafic et influence directement le LCP.
| Technique | Gain | Priorité |
|---|---|---|
| WebP au lieu de JPEG/PNG | 25 à 35 % | Élevée |
| AVIF au lieu de JPEG/PNG | 40 à 55 % | Élevée (prise en charge par plus de 90 % des navigateurs) |
| Compression sans perte (PNG → oxipng) | 5 à 20 % | Moyenne |
| Dimensionnement correct (srcset + sizes) | 50 à 80 % sur mobile | Élevée |
| Lazy loading pour les images hors écran | Économie de requêtes au chargement | Élevée |
| fetchpriority="high" pour l’image LCP | 0,5 à 1,5 s de LCP | Critique |
Utilisez l’élément <picture> pour servir le bon format : AVIF pour les navigateurs compatibles, WebP en repli, JPEG/PNG pour les navigateurs anciens. Le composant Image de Next.js gère cela automatiquement.
Polices
- Hébergez les polices vous-même : servez les fichiers .woff2 depuis votre propre domaine. Cela supprime la résolution DNS, la négociation TCP et la dépendance au CDN de Google Fonts.
- Préchargez les polices critiques : <link rel="preload" as="font" type="font/woff2" crossorigin> dans le <head>. Le navigateur commence le téléchargement avant l’analyse du CSS.
- font-display: swap : le navigateur affiche la police système pendant le chargement de la police personnalisée. Cela supprime le FOIT (texte invisible).
- Subsetting des polices : ne chargez que les glyphes nécessaires (latin + cyrillique). Outils : glyphhanger ou fonttools.
- Utilisez les polices variables : un seul fichier au lieu de plusieurs graisses (regular, bold, italic). Gain de 30 à 50 % sur la taille totale des polices.
CSS
- CSS critique intégré
- Les styles de la partie haute de la page (au-dessus de la ligne de flottaison) sont intégrés directement dans le <head>, dans une balise <style>. Le navigateur affiche le premier écran sans attendre le fichier CSS externe. Le reste du CSS se charge de manière asynchrone.
- Minification
- Suppression des espaces et des commentaires, raccourcissement des propriétés. Outils : Cssnano ou LightningCSS. Gain typique : 10 à 30 % de la taille d’origine.
- Suppression du CSS inutilisé
- PurgeCSS, UnCSS ou le mécanisme intégré du framework (purge de Tailwind). C’est particulièrement important avec Bootstrap ou Material UI, qui embarquent des milliers de règles inutilisées.
- Évitez @import dans le CSS
- Un @import crée des requêtes successives : le navigateur charge le fichier, découvre le @import, puis seulement démarre le chargement du fichier suivant. Utilisez plutôt des balises <link> pour un chargement en parallèle.
JavaScript : ressources bloquantes et thread principal
Le JavaScript est le principal ennemi de Page Speed sur les sites modernes. Il bloque le rendu, occupe le thread principal et retarde l’interactivité. Objectif : le minimum de JS sur le chemin critique, et un usage maximal de defer, async et des imports dynamiques.
Stratégies de chargement
| Attribut | Comportement | Quand l’utiliser |
|---|---|---|
| Aucun | Bloque l’analyse du HTML, s’exécute immédiatement | Uniquement le code critique en ligne |
| async | Se charge en parallèle, s’exécute dès qu’il est prêt (peut interrompre l’analyse) | Scripts indépendants (analytics) |
| defer | Se charge en parallèle, s’exécute après l’analyse du HTML | La plupart des scripts de la page |
| type="module" | Équivalent de defer par défaut + prise en charge des modules ESM | Scripts ESM modernes |
Bundle et code splitting
- Code splitting : découpez le JS en fragments et ne chargez que ce qui est nécessaire à la page courante. Dans Next.js, cela se fait automatiquement page par page.
- Import dynamique : import('module') pour les composants inutiles au premier chargement (fenêtres modales, onglets, filtres).
- Tree shaking : ne compilez que le code réellement utilisé. Webpack et Rollup le font pour les paquets ESM. Vérifiez : certaines dépendances CommonJS ne bloquent-elles pas le tree shaking ?
- Analyse du bundle : bundlephobia.com pour contrôler le poids des paquets npm, @next/bundle-analyzer pour Next.js. Il montre précisément ce qui occupe la place.
- Évitez les grandes bibliothèques monolithiques : moment.js (67 Ko) → day.js (2 Ko), lodash → utilitaires individuels, jQuery → JS natif.
SPA et rendu côté serveur
Les SPA côté client (React sans SSR, Angular, Vue en CSR) renvoient un HTML vide et génèrent le contenu dans le navigateur. Résultat : un LCP élevé et un mauvais Time to Interactive.
- SSR (Server-Side Rendering)
- Le HTML complet est généré sur le serveur. Le navigateur reçoit immédiatement le contenu prêt. Le LCP, le FCP et le score Lighthouse s’améliorent nettement. Cela nécessite une hydratation côté client : surveillez le TTI (Time to Interactive).
- SSG (Static Site Generation)
- Le HTML est généré au moment de la compilation. Le TTFB et le LCP sont au maximum. Convient aux contenus qui changent peu : blog, documentation, pages d’atterrissage.
- PPR (Partial Prerendering)
- Nouveauté de Next.js 15 : une coquille de page statique, avec des parties dynamiques diffusées en streaming. La coquille statique est servie instantanément depuis le CDN, pendant que les données dynamiques arrivent au fur et à mesure qu’elles sont prêtes.
Mise en cache : navigateur et CDN
Une mise en cache bien configurée est l’optimisation la moins coûteuse et la plus efficace pour les visiteurs qui reviennent. Objectif : toutes les ressources statiques en cache pendant un an ; HTML : cache minimal ou nul.
| Type de ressource | Cache-Control | Stratégie d’invalidation |
|---|---|---|
| JS/CSS avec hash (bundle.abc123.js) | max-age=31536000, immutable | Le hash change quand le fichier change |
| Images | max-age=2592000 (30 jours) | URL avec version ou content hash |
| Pages HTML | no-cache ou max-age=0, must-revalidate | Toujours revalidées auprès du serveur |
| Polices | max-age=31536000, immutable | Hash dans l’URL ou versionnement |
| Réponses API | Cache-Control: private, max-age=60 | Dépend de la fréquence de modification des données |
- Hachage basé sur le contenu (fingerprinting) : Webpack, Vite et Next.js ajoutent automatiquement un hash du contenu au nom du fichier. Quand le code change, le hash change aussi et l’ancien cache n’est pas utilisé.
- ETag et Last-Modified : si le client possède déjà la ressource, le serveur répond 304 Not Modified sans corps de réponse. Moins de trafic, mais un aller-retour réseau reste nécessaire.
- Service Worker : cache programmable dans le navigateur. Il permet des stratégies avancées (Cache-First, Network-First, Stale-While-Revalidate) pour les PWA et le fonctionnement hors ligne.
- Cache-Control côté CDN : utilisez s-maxage pour régler le cache du CDN indépendamment du max-age du navigateur. Le CDN met en cache plus longtemps, le navigateur plus court.
Scripts tiers : le coupable caché
Les scripts tiers (analytics, chatbots, pixels, tests A/B, widgets) sont souvent la première cause d’un mauvais TBT et d’un mauvais INP. Une page commerciale moyenne charge de 15 à 30 scripts tiers.
Audit des scripts tiers
L’onglet « Third-party Summary » de WebPageTest indique combien de millisecondes chaque script bloque le thread principal. Les coupables habituels : Intercom, Hotjar, les anciennes versions de Google Analytics (gtag sans async).
Chargement différé
Chargez les scripts non critiques avec un délai : setTimeout(loadScript, 3000) après l’événement load. L’utilisateur peut interagir avec la page avant le chargement de l’outil d’analyse.
DNS prefetch et preconnect
<link rel="preconnect"> pour les domaines que vous sollicitez à coup sûr. <link rel="dns-prefetch"> pour ceux que vous solliciterez probablement. Gain : 100 à 300 ms par résolution DNS et négociation TCP pour chaque domaine tiers.
Remplacer ou supprimer
La meilleure optimisation des scripts tiers reste leur suppression. Pourquoi un chatbot payant sur toutes les pages ? Pourquoi cinq pixels de réseaux sociaux ? L’audit des scripts réellement utilisés révèle souvent que 30 à 50 % d’entre eux sont inutiles.
FAQ
Qu’est-ce qui compte le plus pour le SEO : le score Lighthouse ou les Core Web Vitals ?
En combien de temps les améliorations de Page Speed influencent-elles le classement ?
Que faire si Lighthouse affiche un bon score mais que le site paraît lent ?
L’AMP vaut-il la peine pour accélérer un site ?
Page Speed influence-t-il davantage le classement mobile que le classement desktop ?
Check it with SpiderHead
Free and local: run the audit on your own machine.



