iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
SEO · Intermédiaire

SEO Technique

Comprendre et maîtriser le référencement naturel de A à Z : crawl, indexation, Core Web Vitals, données structurées, maillage interne et Search Console. La formation technique pour développeurs qui veulent que leur site soit trouvé.

Google Search ConsoleSchema.orgCore Web VitalsNext.jsrobots.txt
01Comment Google fonctionne02HTML pour le SEO03Robots.txt, Sitemap et URLs04Maillage interne et contenu dupliqué05Core Web Vitals06Données structurées Schema.org07JavaScript, Search Console et Checklist
Chapitre 5·25 min

Core Web Vitals

Depuis 2021, les Core Web Vitals font partie de l'algorithme de classement de Google. Ce sont trois métriques de performance mesurées sur des données réelles (vraies visites de Chrome), pas sur des tests en laboratoire.

Un mauvais score ne vous fait pas tomber de la première page à la dixième — mais entre deux pages de qualité similaire, celle avec de bons CWV l'emporte. C'est un signal de départage.

Les trois métriques

LCP — Largest Contentful Paint

Ce que ça mesure : le temps d'affichage du plus grand élément visible dans la fenêtre — généralement l'image hero, le titre H1, ou un bloc de texte large.

Objectif : ≤ 2,5 secondes.

< 2,5s  → Bon (vert)
2,5-4s  → À améliorer (orange)
> 4s    → Mauvais (rouge)

Causes fréquentes de LCP lent :

CauseImpactSolution
Image hero lourde (PNG 2Mo)MajeurWebP + compression
TTFB > 600ms (serveur lent)MajeurCache, CDN
CSS render-blockingModéré<link rel=preload>
loading="lazy" sur l'image heroModéréSupprimer lazy sur hero
Polices en blockingMineurfont-display: swap

Solutions concrètes :

<!-- ✅ Précharger l'image LCP dès le head -->
<link
  rel="preload"
  as="image"
  href="/hero.webp"
  fetchpriority="high"
>
 
<!-- ✅ L'image hero : high priority, pas de lazy -->
<img
  src="/hero.webp"
  alt="Description"
  width="1200"
  height="600"
  fetchpriority="high"
>
 
<!-- ❌ Jamais loading=lazy sur l'image au-dessus du fold -->
<img src="/hero.webp" loading="lazy">
/* ✅ Font-display swap — le texte s'affiche immédiatement avec la police système */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap;
}

CLS — Cumulative Layout Shift

Ce que ça mesure : la stabilité visuelle de la page — combien les éléments se déplacent pendant le chargement, au total.

Objectif : ≤ 0,1

< 0,1   → Bon (vert)
0,1-0,25 → À améliorer (orange)
> 0,25  → Mauvais (rouge)

Vous avez sûrement vécu un mauvais CLS : vous êtes sur le point de cliquer sur un lien, une bannière se charge et pousse le contenu vers le bas — vous cliquez sur la mauvaise chose.

Causes fréquentes :

Images sans dimensions :

<!-- ❌ Le navigateur ne connaît pas la taille avant le chargement → décalage -->
<img src="photo.jpg" alt="...">
 
<!-- ✅ Dimensions explicites — le navigateur réserve l'espace -->
<img src="photo.webp" alt="..." width="800" height="450">

Iframes et publicités sans dimensions :

<!-- ❌ -->
<iframe src="video.html"></iframe>
 
<!-- ✅ -->
<div style="aspect-ratio: 16/9; position: relative">
  <iframe src="video.html" style="position: absolute; inset: 0; width: 100%; height: 100%"></iframe>
</div>

Polices qui s'échangent (FOUT) : Le texte s'affiche d'abord avec une police système (petite), puis avec la police custom (plus grande) — le texte repousse les éléments qui suivent. Solution : font-display: swap + polices préchargées.

Éléments injectés dynamiquement :

// ❌ Injecter une bannière au-dessus du contenu existant
document.body.insertBefore(banner, document.body.firstChild)
 
// ✅ Réserver de l'espace dès le départ
// <div class="banner-placeholder" style="min-height: 60px"></div>

INP — Interaction to Next Paint

Ce que ça mesure : la réactivité aux interactions utilisateur (clics, touches clavier, tapotements). INP remplace FID depuis mars 2024.

Objectif : ≤ 200ms

< 200ms  → Bon (vert)
200-500ms → À améliorer (orange)
> 500ms  → Mauvais (rouge)

Un mauvais INP signifie que votre site "répond" lentement aux actions utilisateur — bouton qui ne réagit pas immédiatement, champ de saisie avec lag.

Causes fréquentes :

  • Long Tasks JavaScript sur le thread principal (> 50ms)
  • Bundle JavaScript monolithique (tout chargé dès le départ)
  • Événements click ou keydown avec des calculs lourds

Solutions :

// ❌ Calcul lourd sur le thread principal = UI gelée
button.addEventListener('click', () => {
  const result = heavyComputation(largeDataset)  // Bloque l'UI pendant 500ms
  displayResult(result)
})
 
// ✅ Découper avec setTimeout ou scheduler
button.addEventListener('click', () => {
  setTimeout(() => {
    const result = heavyComputation(largeDataset)
    displayResult(result)
  }, 0)  // Laisse l'UI se mettre à jour d'abord
})
 
// ✅ Web Worker pour les vrais calculs lourds
const worker = new Worker('/worker.js')
button.addEventListener('click', () => {
  worker.postMessage(largeDataset)
})
worker.onmessage = (e) => displayResult(e.data)
// ✅ Code splitting Next.js — ne charger que ce qui est nécessaire
import dynamic from 'next/dynamic'
 
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <Skeleton />,
})

Mesurer les Core Web Vitals

Google Search Console (données réelles)

Search Console → Expérience → Core Web Vitals — la source la plus fiable. Données issues de vraies visites Chrome, sur 28 jours glissants.

Le rapport distingue :

  • Mobile et Desktop
  • Pages "Bonnes", "À améliorer", "Mauvaises"
  • URLs spécifiques avec problème

PageSpeed Insights (lab + terrain)

https://pagespeed.web.dev/ — analyse une URL spécifique et combine données de lab (Lighthouse) et données terrain (CrUX).

Lighthouse (local)

# Via CLI
npm install -g lighthouse
lighthouse https://iducation.fr --output html --output-path ./report.html
 
# Ou dans Chrome DevTools → Lighthouse → Analyser la page

Web Vitals en JavaScript (monitoring)

Mesurer les CWV en temps réel
import { onLCP, onCLS, onINP } from 'web-vitals'
 
function sendToAnalytics(metric) {
  console.log(metric.name, metric.value, metric.rating)
  // Envoyer à votre outil de monitoring (Datadog, custom endpoint...)
  fetch('/api/vitals', {
    method: 'POST',
    body: JSON.stringify(metric),
  })
}
 
onLCP(sendToAnalytics)
onCLS(sendToAnalytics)
onINP(sendToAnalytics)

Checklist Core Web Vitals

LCP

  • Image hero en WebP ou AVIF
  • fetchpriority="high" sur l'image hero
  • Pas de loading="lazy" sur l'image au-dessus du fold
  • <link rel="preload" as="image"> pour l'image LCP
  • TTFB < 600ms (hébergeur, CDN, cache serveur)
  • font-display: swap pour les polices custom

CLS

  • width et height sur toutes les images et vidéos
  • aspect-ratio en CSS pour les conteneurs d'iframes
  • Espace réservé pour les bannières/publicités
  • Polices préchargées pour éviter le FOUT
  • Pas d'injection dynamique au-dessus du contenu visible

INP

  • Pas de Long Tasks > 50ms sur le thread principal
  • Code splitting pour le JavaScript non-critique
  • Web Workers pour les calculs lourds
  • Gestionnaires d'événements légers

À faire : Testez votre site sur pagespeed.web.dev. Notez les scores LCP, CLS, INP pour mobile et desktop. Identifiez le premier problème de chaque métrique (Search Console ou PageSpeed vous dit quelle ressource est responsable) et appliquez la solution correspondante.

Précédent
Maillage interne et contenu dupliqué
Suivant
Données structurées Schema.org

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main