← Tous les articles

API et helpers

Moniteur Web Vitals dans l'onglet — LCP / CLS / INP dans l'Output Console sans DevTools

Les Web Vitals (LCP, CLS, INP) sont 3 métriques que Google utilise comme facteur de classement SEO. La façon standard de les mesurer : Lighthouse dans les DevTools — 30 secondes par audit, déclenchement manuel. Alternative : l'API PerformanceObserver intégrée aux navigateurs. Plus une règle JS JustZix = un moniteur passif qui rapporte dans l'Output Console pour chaque page visitée. Parfait pour un contrôle rapide de vos propres projets ou l'analyse des concurrents.

Règle JS — capture complète des Web Vitals

Scope : *://*/* ou par domaine si vous voulez seulement surveiller vos propres sites.

// Règle JS « Moniteur Web Vitals »
const vitals = { LCP: null, CLS: 0, FCP: null, TTFB: null, INP: null };

// === LCP (Largest Contentful Paint) ===
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const last = entries[entries.length - 1];
  vitals.LCP = Math.round(last.startTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });

// === CLS (Cumulative Layout Shift) ===
let clsEntries = [];
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      clsEntries.push(entry);
      vitals.CLS = clsEntries.reduce((s, e) => s + e.value, 0);
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

// === FCP (First Contentful Paint) ===
new PerformanceObserver((list) => {
  const fcp = list.getEntries().find(e => e.name === 'first-contentful-paint');
  if (fcp) vitals.FCP = Math.round(fcp.startTime);
}).observe({ type: 'paint', buffered: true });

// === TTFB (Time to First Byte) ===
const nav = performance.getEntriesByType('navigation')[0];
if (nav) vitals.TTFB = Math.round(nav.responseStart - nav.requestStart);

// === INP (Interaction to Next Paint) ===
let worstINP = 0;
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > worstINP) {
      worstINP = Math.round(entry.duration);
      vitals.INP = worstINP;
    }
  }
}).observe({ type: 'event', buffered: true, durationThreshold: 16 });

// Rapport 5 secondes après le chargement + au unload (valeurs finales)
const report = () => {
  const status = (val, good, poor) =>
    val === null ? '?' : val <= good ? '✓' : val <= poor ? '⚠' : '✗';

  JUSTZIX.log('=== Web Vitals ===');
  JUSTZIX.log(`LCP:  ${vitals.LCP ?? '?'}ms  ${status(vitals.LCP, 2500, 4000)} (cible <2.5s)`);
  JUSTZIX.log(`CLS:  ${vitals.CLS.toFixed(3)}  ${status(vitals.CLS, 0.1, 0.25)} (cible <0.1)`);
  JUSTZIX.log(`FCP:  ${vitals.FCP ?? '?'}ms  ${status(vitals.FCP, 1800, 3000)} (cible <1.8s)`);
  JUSTZIX.log(`TTFB: ${vitals.TTFB ?? '?'}ms  ${status(vitals.TTFB, 800, 1800)} (cible <800ms)`);
  JUSTZIX.log(`INP:  ${vitals.INP ?? '?'}ms  ${status(vitals.INP, 200, 500)} (cible <200ms)`);
};

setTimeout(report, 5000);
window.addEventListener('beforeunload', report);
JUSTZIX.info(`[Vitals] Moniteur actif pour ${location.hostname}`);

Ce que vous voyez dans l'Output Console

5 secondes après le chargement :

[INFO]  [Vitals] Moniteur actif pour www.justzix.com
[LOG]   === Web Vitals ===
[LOG]   LCP:  1240ms  ✓ (cible <2.5s)
[LOG]   CLS:  0.024   ✓ (cible <0.1)
[LOG]   FCP:  680ms   ✓ (cible <1.8s)
[LOG]   TTFB: 145ms   ✓ (cible <800ms)
[LOG]   INP:  85ms    ✓ (cible <200ms)

Chaque métrique avec un statut visuel :

Cas d'usage 1 — auditer votre propre site sans Lighthouse

Classique : déployer sur staging, ouvrir l'onglet, vérifier si les Web Vitals sont au vert. Avec Lighthouse : 30 s d'attente. Avec JustZix : 5 s, et il rapporte pour chaque page suivante visitée dans cette session.

Cas d'usage 2 — comparer aux concurrents

Visitez un concurrent. L'Output Console affiche ses LCP/CLS/INP. Votre site — comparaison 1:1, mêmes conditions réseau, même appareil.

Cas d'usage 3 — moniteur en direct pendant le développement

Snappez un pane Output Console sur le côté droit. Lancez votre serveur dev localhost. Chaque F5 → un JUSTZIX.log avec des vitals fraîches. Vous voyez en direct l'effet de vos changements (p. ex. image lazy-load → LCP en hausse, layout shift → CLS en hausse).

Cas d'usage 4 — export JSON avec une action BOUTON

// Action BOUTON « 📊 Exporter les vitals »
const data = {
  url: location.href,
  timestamp: new Date().toISOString(),
  vitals: window.JZ_LATEST_VITALS || {}
};
const json = JSON.stringify(data, null, 2);
navigator.clipboard.writeText(json);
JUSTZIX.log('Vitals exportées vers le presse-papiers.');

Dans la règle JS, ajoutez une ligne : window.JZ_LATEST_VITALS = vitals; après chaque mise à jour. Le BOUTON a maintenant le snapshot courant à exporter vers la doc / Slack.

Pièges

La suite

Installez JustZix — un moniteur Web Vitals zéro-config qui REMARQUE le problème avant l'utilisateur.

Notez cet article

Aucune note — soyez le premier.

Essayez vous-même

Installez JustZix et collez n'importe quel snippet de cet article. Deux minutes de zéro à une règle fonctionnelle sur tous vos appareils.

Obtenir JustZix

Fonctionnalités · Comment ça marche · Exemples · Cas d'usage