RAICODE
ProcessusProjetsBlogOffresClientsWhatsApp
Performance

Comment J'ai Réduit le Temps de Chargement de 8s à 0.8s (Case Study)

Étape par étape, les optimisations exactes qui ont transformé un site e-commerce lent en fusée.

Mustapha Hamadi
Développeur Full-Stack
13 décembre 2025
8 min read
Comment J'ai Réduit le Temps de Chargement de 8s à 0.8s (Case Study)
#performance#Core Web Vitals#optimisation#case study#e-commerce
Partager :

title: "Comment J'ai Réduit le Temps de Chargement de 8s à 0.8s (Case Study)" description: "Étape par étape, les optimisations exactes qui ont transformé un site e-commerce lent en fusée." date: "2025-12-13" author: "Équipe Raicode" tags: ["performance", "Core Web Vitals", "optimisation", "case study", "e-commerce"] category: "Performance" image: "/blog/temps-chargement-8s-08s-hero.png" ogImage: "/blog/temps-chargement-8s-08s-hero.png" keywords: ["optimisation performance web", "temps de chargement", "Core Web Vitals", "vitesse site web", "LCP optimisation"]

Le site : Un e-commerce de mode avec 3 500 produits. Le problème : 8.2 secondes de chargement sur mobile. Taux de rebond à 67%. Le résultat : 0.83 secondes. Taux de rebond à 31%. CA +47% en 3 mois.

Voici exactement ce qu'on a fait.


L'Audit Initial : L'Horreur

Les Métriques de Départ

Lighthouse Mobile : 23/100 💀
LCP (Largest Contentful Paint) : 8.2s
FID (First Input Delay) : 340ms
CLS (Cumulative Layout Shift) : 0.42
Time to Interactive : 12.4s
Total Page Weight : 14.2 MB

Les Problèmes Identifiés

  1. Images non optimisées : Photos produits en 4000x4000px, format JPG
  2. JavaScript bloquant : 47 scripts tiers (analytics, chat, pixels...)
  3. Pas de mise en cache : Tout rechargé à chaque visite
  4. Serveur lent : Hébergement mutualisé cheap
  5. Fonts personnalisées : 6 variantes chargées en render-blocking
  6. Carrousel géant : 12 images en autoplay sur la homepage
  7. Base de données non optimisée : Requêtes en 2-3 secondes

Phase 1 : Les Quick Wins (Jour 1-2)

Optimisation #1 : Images → -4.2s

Avant :

<img src="product-photo.jpg" />
<!-- 4000x4000px, 2.8MB par image -->

Après :

<img
  src="product-photo.webp"
  srcset="
    product-photo-400.webp 400w,
    product-photo-800.webp 800w,
    product-photo-1200.webp 1200w
  "
  sizes="(max-width: 768px) 100vw, 50vw"
  loading="lazy"
  decoding="async"
  width="800"
  height="800"
/>

Actions :

  • Conversion automatique en WebP (85% de compression en plus)
  • Génération de variantes responsive
  • Lazy loading sur toutes les images below the fold
  • Dimensions explicites pour éviter le CLS

Impact : -4.2s de LCP, -8.7MB de poids total


Optimisation #2 : Scripts Tiers → -1.8s

Avant : 47 scripts chargés en synchrone

<script src="analytics.js"></script>
<script src="chat-widget.js"></script>
<script src="facebook-pixel.js"></script>
<script src="hotjar.js"></script>
<!-- ... 43 autres -->

Après :

<!-- Scripts critiques uniquement, différés -->
<script defer src="analytics-minimal.js"></script>

<!-- Le reste chargé après interaction utilisateur -->
<script>
  // Chargement lazy des scripts non-critiques
  document.addEventListener('scroll', () => {
    loadNonCriticalScripts();
  }, { once: true });

  setTimeout(loadNonCriticalScripts, 5000);
</script>

Actions :

  • Suppression de 23 scripts inutiles ou redondants
  • Defer/async sur tous les scripts restants
  • Chargement conditionnel (chat après scroll, pixels après consentement)
  • Bundle des scripts similaires

Impact : -1.8s de Time to Interactive


Optimisation #3 : Fonts → -0.6s

Avant :

@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-regular.woff2');
  /* 6 variantes, toutes chargées au démarrage */
}

Après :

@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom-regular.woff2');
  font-display: swap;
  unicode-range: U+0000-00FF; /* Latin de base uniquement */
}

/* Préchargement de la font critique */
<link rel="preload" href="/fonts/custom-regular.woff2" as="font" crossorigin>

Actions :

  • Réduction à 2 variantes (regular + bold)
  • Subsetting (caractères latins uniquement)
  • font-display: swap pour éviter le blocage
  • Préchargement de la font principale

Impact : -0.6s, CLS éliminé sur les textes


Phase 2 : Infrastructure (Jour 3-5)

Optimisation #4 : Changement d'Hébergement → -0.9s

Avant : Hébergement mutualisé OVH à 5€/mois

  • TTFB : 1.2s
  • Pas de HTTP/2
  • Pas de CDN

Après : Vercel (frontend) + Railway (backend)

  • TTFB : 0.08s
  • HTTP/3 activé
  • CDN global automatique

Impact : -0.9s de TTFB, meilleure distribution mondiale


Optimisation #5 : Mise en Cache Aggressive

Configuration CDN :

# Assets statiques : 1 an
Cache-Control: public, max-age=31536000, immutable

# Pages HTML : revalidation
Cache-Control: public, max-age=0, must-revalidate

# Images produits : 1 semaine
Cache-Control: public, max-age=604800

Service Worker pour offline-first :

// Cache des pages déjà visitées
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

Impact : Visiteurs récurrents à 0.3s de chargement


Optimisation #6 : Base de Données → -0.5s

Problèmes identifiés :

  • Requêtes N+1 sur les pages catégories
  • Pas d'index sur les colonnes filtrées
  • Jointures non optimisées

Solutions :

-- Ajout d'index stratégiques
CREATE INDEX idx_products_category_price
ON products(category_id, price);

CREATE INDEX idx_products_active_stock
ON products(is_active, stock_quantity);
// Avant : N+1 queries
const products = await db.products.findAll();
for (const p of products) {
  p.category = await db.categories.findById(p.categoryId);
}

// Après : 1 query avec jointure
const products = await db.products.findAll({
  include: [{ model: Category }]
});

Impact : -0.5s sur les pages catalogue


Phase 3 : Optimisations Avancées (Jour 6-10)

Optimisation #7 : Code Splitting

Avant : Un seul bundle JavaScript de 2.3MB

// Tout importé au démarrage
import HomePage from './pages/HomePage';
import ProductPage from './pages/ProductPage';
import CartPage from './pages/CartPage';
import CheckoutPage from './pages/CheckoutPage';
// ... 47 autres composants

Après : Chargement à la demande

// Import dynamique
const HomePage = lazy(() => import('./pages/HomePage'));
const ProductPage = lazy(() => import('./pages/ProductPage'));

// Route-based splitting
<Route path="/" element={
  <Suspense fallback={<Skeleton />}>
    <HomePage />
  </Suspense>
} />

Impact : Bundle initial de 287KB (vs 2.3MB)


Optimisation #8 : Préchargement Intelligent

<!-- Préconnexion aux domaines tiers -->
<link rel="preconnect" href="https://cdn.shopify.com">
<link rel="dns-prefetch" href="https://analytics.google.com">

<!-- Préchargement des ressources critiques -->
<link rel="preload" href="/hero-image.webp" as="image">
<link rel="preload" href="/critical.css" as="style">

<!-- Prefetch des pages probables -->
<link rel="prefetch" href="/products">

Prefetch au survol :

// Quand l'utilisateur survole un lien, précharge la page
document.querySelectorAll('a').forEach(link => {
  link.addEventListener('mouseenter', () => {
    const href = link.getAttribute('href');
    if (href.startsWith('/')) {
      const prefetchLink = document.createElement('link');
      prefetchLink.rel = 'prefetch';
      prefetchLink.href = href;
      document.head.appendChild(prefetchLink);
    }
  }, { once: true });
});

Impact : Navigation perçue quasi-instantanée


Optimisation #9 : Critical CSS

Avant : 1 fichier CSS de 450KB chargé en bloquant

Après :

<!-- CSS critique inline -->
<style>
  /* Styles pour above-the-fold uniquement */
  .header { ... }
  .hero { ... }
  .nav { ... }
</style>

<!-- CSS complet en async -->
<link rel="preload" href="/styles.css" as="style" onload="this.rel='stylesheet'">

Génération automatique avec Critters :

// next.config.js
module.exports = {
  experimental: {
    optimizeCss: true,
  },
};

Impact : First Paint -0.8s


Optimisation #10 : Suppression du Carrousel

Le problème : Le carrousel homepage chargeait 12 images de 2MB chacune au démarrage.

La solution : Remplacement par une seule hero image avec CTA clair.

// Avant
<Carousel images={heroImages} autoPlay interval={3000} />

// Après
<HeroImage
  src="/hero-optimized.webp"
  alt="Collection Été 2025"
  priority
/>

Bonus : Les carrousels ont un taux de clic de 1% en moyenne. Une image unique avec bon CTA convertit mieux.

Impact : -12MB, +23% de clics sur le CTA


Les Résultats Finaux

Métriques Après Optimisation

Lighthouse Mobile : 98/100 ✅ (était 23)
LCP : 0.83s ✅ (était 8.2s)
FID : 12ms ✅ (était 340ms)
CLS : 0.01 ✅ (était 0.42)
Time to Interactive : 1.1s ✅ (était 12.4s)
Total Page Weight : 890KB ✅ (était 14.2MB)

Impact Business

| Métrique | Avant | Après | Évolution | |----------|-------|-------|-----------| | Taux de rebond | 67% | 31% | -54% | | Pages/session | 2.1 | 4.7 | +124% | | Durée session | 1:12 | 3:45 | +212% | | Taux conversion | 1.2% | 2.1% | +75% | | CA mensuel | - | - | +47% |


La Checklist Performance

Quick Wins (Impact immédiat)

  • [ ] Images en WebP avec srcset
  • [ ] Lazy loading sur images below the fold
  • [ ] Scripts en defer/async
  • [ ] Fonts avec font-display: swap
  • [ ] Suppression scripts inutiles

Infrastructure

  • [ ] TTFB < 200ms
  • [ ] CDN activé
  • [ ] HTTP/2 ou HTTP/3
  • [ ] Cache headers configurés
  • [ ] Compression Brotli/Gzip

Avancé

  • [ ] Code splitting par route
  • [ ] Critical CSS inline
  • [ ] Service Worker
  • [ ] Prefetch intelligent
  • [ ] Optimisation BDD

Les Outils Utilisés

| Outil | Usage | |-------|-------| | Lighthouse | Audit initial et suivi | | WebPageTest | Tests multi-localisations | | Chrome DevTools | Debug réseau et performance | | Squoosh | Optimisation images manuelle | | Bundle Analyzer | Analyse du JavaScript | | Sentry | Monitoring performance réelle |


Le Mot de la Fin

La performance n'est pas un luxe. C'est un investissement avec un ROI mesurable.

Chaque seconde de chargement en moins = 7% de conversion en plus (source: Portent).

Le site de ce case study n'avait rien de spécial techniquement. Les mêmes optimisations s'appliquent à 90% des sites web.

La question n'est pas "si" vous devez optimiser, mais "quand".


Votre site rame ? On réalise un audit performance gratuit avec rapport détaillé des optimisations prioritaires. Demander un audit

Partager :

Prêt à lancer votre projet ?

Transformez vos idées en réalité avec un développeur passionné par la performance et le SEO. Discutons de votre projet dès aujourd'hui.

Discuter sur WhatsApp
Voir mes réalisations
Réponse < 48h
15+ projets livrés
100% satisfaction client

Table des matières

Articles similaires

Les 10 Erreurs de Performance Web Qui Font Fuir Vos Visiteurs
Performance

Les 10 Erreurs de Performance Web Qui Font Fuir Vos Visiteurs

10 février 2026
10 min read
Temps de Chargement : Comment Passer Sous les 2 Secondes
performance

Temps de Chargement : Comment Passer Sous les 2 Secondes

4 décembre 2025
12 min read
Optimisation des Images Web : Guide Complet pour Accélérer Votre Site
Développement

Optimisation des Images Web : Guide Complet pour Accélérer Votre Site

19 mars 2026
13 min read
RAICODE

Développeur Full-Stack spécialisé en Next.js & React.
Je crée des applications web performantes et sur mesure.

SERVICES

  • Sites Vitrines
  • Applications SaaS
  • E-commerce
  • API & Backend

NAVIGATION

  • Processus
  • Projets
  • Blog
  • Tarifs
  • Contact

LÉGAL

  • Mentions légales
  • Confidentialité
  • CGU
  • CGV

© 2026 Raicode. Tous droits réservés.

Créé parRaicode.
↑ Retour en haut