RAICODE
ProcessusProjetsBlogOffresClientsContact
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.

Demander un devis
Voir mes réalisations
Réponse < 48h
15+ projets livrés
100% satisfaction client

Table des matières

Articles similaires

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
Core Web Vitals 2025 : Le Guide Complet pour Optimiser vos Performances Web
SEO

Core Web Vitals 2025 : Le Guide Complet pour Optimiser vos Performances Web

2 décembre 2025
10 min read
Comment optimiser le SEO de votre site Next.js en 2025
SEO

Comment optimiser le SEO de votre site Next.js en 2025

15 janvier 2025
4 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

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

Créé parRaicode.
↑ Retour en haut