BaliseTonSite

Viser le 100/100 sur Google Lighthouse

Guide complet pour optimiser les scripts, les images et le rendu afin de décrocher le score parfait sur Google Lighthouse.

Imagine : tu as un perso de haut niveau, mais ton équipement n'est pas optimisé. Tu portes une armure lourde inutile, des potions périmées, et des armes que tu n'utilises pas. Résultat tu es lent. L'optimisation chirurgicale, c'est alléger ton inventaire pour devenir ultra-rapide.

8.1Les polices, alléger la fonte

Les polices web sont souvent un point de blocage au chargement. Une police mal chargée peut ruiner ton LCP et provoquer du CLS (le texte qui « saute » quand la police arrive enfin).

/* Mauvais  import Google Fonts bloquant */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');

/* Bon en Next.js  import optimisé automatique */
// layout.tsx
import { Inter } from 'next/font/google';

const inter = Inter({ 
    subsets: ['latin'],
    display: 'swap',        // Affiche un fallback en attendant
    preload: true,           // Précharge la police
});

export default function Layout({ children }) {
    return <body className={inter.className}>{children}</body>;
}
  • font-display: swap affiche le texte immédiatement avec un fallback
  • Self-hosting héberge la police sur ton serveur (pas de requête externe)
  • Subset ne charge que les caractères dont tu as besoin (latin, pas cyrillique)
  • Limiter les graisses charge seulement 400 et 700, pas les 18 variantes

Charger toutes les polices avec toutes les graisses, c'est comme porter toutes les armures du jeu en même temps « au cas où ». Ton perso est lent. Choisis seulement ce dont tu as besoin.

8.2Le payload JavaScript, réduire le poids du build

Chaque librairie que tu importes ajoute du poids à ton bundle JavaScript. Un bundle lourd = un site lent = un mauvais score. L'objectif n'embarquer que ce que tu utilises.

// Import complet  charge toute la librairie (~70 Ko)
import _ from 'lodash';
_.debounce(fn, 300);

// Import ciblé  charge seulement la fonction (~1 Ko)
import debounce from 'lodash/debounce';
debounce(fn, 300);

// Encore mieux  écris ta propre version simple
function debounce(fn, delay) {
    let timer;
    return (...args) => {
     clearTimeout(timer);
     timer = setTimeout(() => fn(...args), delay);
    };
}
  • Tree shaking les bundlers modernes suppriment le code non utilisé
  • Imports ciblés n'importe que les fonctions dont tu as besoin
  • Dynamic imports charge les composants lourds uniquement quand nécessaire
  • Analyse le bundle utilise @next/bundle-analyzer pour voir ce qui pèse
// Dynamic import - ne charge le composant que quand on en a besoin
import dynamic from 'next/dynamic';

const HeavyEditor = dynamic(() => import('./CodeEditor'), {
    loading: () => <p>Chargement de l'éditeur...</p>,
    ssr: false,  // Pas besoin côté serveur
});

8.3Les images avancées, le système de LOD

Au chapitre 4, on a vu les bases. Ici, on passe au niveau pro avec les images responsives et le composant <Image> de Next.js.

<!-- Images responsives natives HTML -->
<picture>
    <source srcset="hero-800.avif" type="image/avif" />
    <source srcset="hero-800.webp" type="image/webp" />
    <img src="hero-800.jpg" alt="Hero section" width="800" height="400" />
</picture>

<!-- Avec srcset pour différentes tailles d'écran -->
<img 
    srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
    sizes="(max-width: 768px) 100vw, 800px"
    src="photo-800.webp"
    alt="Illustration du cours"
    loading="lazy"
/>
// Next.js - Le composant Image optimise tout automatiquement
import Image from 'next/image';

export function HeroSection() {
    return (
     <Image
       src="/hero.jpg"
       alt="Guide SEO complet"
       width={1200}
       height={630}
       priority          // Précharge (pour le LCP)
       placeholder="blur" // Effet blur pendant le chargement
     />
    );
}
  • Format AVIF > WebP > JPEG toujours servir le plus léger possible
  • srcset + sizes servir la bonne taille selon l'écran
  • priority sur l'image la plus importante (LCP)
  • placeholder blur meilleure UX pendant le chargement

Le LOD (Level of Detail) dans les jeux charge une texture basse résolution de loin, puis la remplace quand tu t'approches. Le srcset, c'est pareil mobile = petite image, desktop = grande image. Chaque appareil reçoit la texture adaptée.

8.4La checklist du 100/100

Voici ta checklist pour viser le score parfait sur Lighthouse :

  • Polices self-hosted avec font-display: swap
  • Images en WebP/AVIF avec width, height et loading="lazy"
  • Image LCP avec priority / fetchpriority="high"
  • Bundle JS minimal (imports ciblés, dynamic imports)
  • CSS critique inline, le reste en lazy
  • Pas de render-blocking resources
  • Compression Gzip/Brotli activée sur le serveur
  • Cache HTTP configuré (headers Cache-Control)
  • Pas de layout shift dimensions réservées pour images et iframes
  • Server Components par défaut (Next.js App Router)

Le 100/100, c'est le mode Hardcore du SEO technique. C'est pas obligatoire (90+ suffit pour être compétitif), mais c'est la fierté de tout dev perfectionniste. Et maintenant, tu as la recette.

Verifie tes acquis

3 questions pour valider ce chapitre

1. Quel score Lighthouse est considere comme "bon" ?

Valide et sauvegarde ce chapitre

Ne perds pas le fil de ton apprentissage. Chaque QCM complété s'enregistre comme un checkpoint dans ton tableau de bord personnel. Crée ton profil de développeur gratuitement pour débloquer toutes les évaluations du site et suivre ta progression étape par étape.

Commencer l'aventure
Déjà membre ?Connecte-toi