Mon portfolio avait un score PageSpeed de 42 sur mobile. Quarante-deux. J'avais passé des semaines à soigner le design, l'UX, le contenu et Google me notait comme un site des années 2000. C'était il y a 6 mois. En deux heures d'optimisations ciblées, je suis passé à 98. Voici exactement ce que j'ai fait.
Mesurer avant d'optimiser
Règle absolue : ne jamais optimiser à l'aveugle. Avant de toucher quoi que ce soit, mesurez avec :
- PageSpeed Insights (pagespeed.web.dev) l'outil officiel Google, test sur mobile ET desktop
- Chrome DevTools > Lighthouse pour un audit local
- WebPageTest.org pour des tests depuis plusieurs localisations
Identifiez vos trois métriques Core Web Vitals les plus dégradées : LCP, FID/INP, CLS. C'est là que vous devez concentrer vos efforts.
Optimisation #1 : Les images (le coupable numéro 1)
Dans mon cas, des images PNG de 2 Mo qui auraient dû faire 80 Ko. Les images représentent en moyenne 60 à 70% du poids d'une page web. C'est votre première cible.
<!-- ❌ Avant : image lourde, format sous-optimal -->
<img src="hero.png" width="1200" height="600" alt="Hero image">
<!-- ✅ Après : WebP, srcset, dimensions explicites, lazy loading -->
<picture>
<source srcset="hero.webp 1200w, hero-600.webp 600w" type="image/webp">
<img src="hero.jpg"
width="1200"
height="600"
alt="DEZ Koffi — Développeur Laravel"
loading="lazy"
decoding="async">
</picture>
Résultat sur mon site : économie de 1,8 Mo. LCP passé de 4,2s à 1,9s.
Optimisation #2 : Minifier et différer le CSS et JavaScript
Tout fichier CSS ou JS bloque le rendu de la page s'il est chargé dans le <head> sans les bons attributs. Solution :
<!-- CSS critique inline, le reste asynchrone -->
<style>
/* Style critique above-the-fold uniquement */
body { font-family: sans-serif; margin: 0; }
.hero { height: 100vh; background: #0f172a; }
</style>
<!-- CSS non-critique : chargement asynchrone -->
<link rel="preload" href="/css/app.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<!-- JS : toujours avec defer ou async -->
<script src="/js/app.js" defer></script>
Optimisation #3 : Activer la compression Gzip/Brotli sur Nginx
# Dans votre nginx.conf
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1024;
gzip_comp_level 6;
# Brotli (encore mieux, si disponible)
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript;
Résultat : réduction de 60 à 80% du poids des fichiers texte.
Optimisation #4 : Cache navigateur agressif
# Nginx : cache fort pour les assets statiques (1 an)
location ~* \.(jpg|jpeg|png|webp|gif|svg|ico|css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
}
# HTML : pas de cache pour garantir le contenu frais
location ~* \.html$ {
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
Optimisation #5 : Précharger les ressources critiques
<!-- Précharger la police principale -->
<link rel="preload" href="/fonts/inter-v13-latin-regular.woff2"
as="font" type="font/woff2" crossorigin>
<!-- Préconnecter aux domaines externes -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
<!-- Précharger l'image hero (LCP) -->
<link rel="preload" href="/images/hero.webp" as="image">
Optimisation #6 : Éliminer le Layout Shift (CLS)
Le Layout Shift se produit quand des éléments bougent pendant le chargement .
Images sans dimensions, polices qui s'appliquent tardivement, iframes. Solution :
/* Toujours définir width/height sur les images */
img { aspect-ratio: attr(width) / attr(height); }
/* Réserver l'espace pour les fonts */
@font-face {
font-display: swap; /* ou optional pour éviter tout FOUC */
}
/* Réserver l'espace pour les embeds */
.video-container {
aspect-ratio: 16/9;
}
Optimisation #7 : Laravel - Cache et optimisation backend
Côté Laravel, quelques commandes qui changent tout en production :
# Mettre tout en cache
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
# Optimiser l'autoload Composer
composer install --optimize-autoloader --no-dev
# Activer l'OPcache PHP dans php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.jit_buffer_size=100M
Avant / Après : les métriques réelles
| Métrique | Avant | Après |
|---|---|---|
| Score PageSpeed Mobile | 42 | 98 |
| LCP | 4,2s | 1,1s |
| CLS | 0,24 | 0,01 |
| Poids total de la page | 3,4 Mo | 0,8 Mo |
| Temps de chargement (3G) | 8,1s | 2,3s |
Deux heures de travail. Un impact direct sur le SEO et l'expérience utilisateur. C'est l'un des meilleurs retours sur investissement que j'ai réalisé sur ce site.