eduardweb.
SEO & PerformanceIntermediar#performance#seo#nextjs#monitoring#web-vitals

Core Web Vitals în prod: de ce te minte Lighthouse și ce alegi între Vercel Analytics și RUM custom

De Delia Petre, 30 iul. 2026 · 9 vizualizări · 2 like-uri

Postat 30 iul. 2026
typescript
import { onLCP, onINP, onCLS, Metric } from 'web-vitals';

function sendToAnalytics(metric: Metric) {
  const body = JSON.stringify({
    name: metric.name,
    value: metric.value,
    rating: metric.rating, // 'good' | 'needs-improvement' | 'poor'
    delta: metric.delta,
    id: metric.id,
    page: window.location.pathname
  });

  // Beacon garantează că request-ul pleacă chiar dacă tab-ul se închide
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/api/vitals', body);
  } else {
    fetch('/api/vitals', { 
      body, 
      method: 'POST', 
      keepalive: true, 
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

export function initWebVitals() {
  onLCP(sendToAnalytics);
  onINP(sendToAnalytics);
  onCLS(sendToAnalytics);
}

Am mutat recent sistemul de monitorizare pentru un magazin online cu peste 45k de sesiuni zilnice și mi-am adus aminte cât de periculoasă e încrederea orbească în Lighthouse. Dacă rulezi un audit în Chrome DevTools pe un M2 cu conexiune gigabit, toate scorurile sunt verzi. În producție însă, 40% din utilizatori vin de pe telefoane Android ieftine, cu conexiuni 4G instabile și rețele aglomerate.

De ce te fură peisajul cu Lab Data

Scorurile din DevTools (ce numim Lab Data) sunt utile doar ca sanity check în CI/CD ca să nu bagi regresii evidente. Pentru Google și SEO contează exclusiv datele de teren din CrUX (Chrome User Experience Report), adică Real User Monitoring (RUM).

De când INP (Interaction to Next Paint) a înlocuit definitiv bătrânul FID, lucrurile s-au complicat. INP nu măsoară doar prima interacțiune, ci latența tuturor click-urilor, tap-urilor și apăsărilor de taste pe toată durata vizitei. Am avut cazul recent unde LCP-ul era de 1.2 secunde (excelent), dar INP-ul sărea frecvent de 350ms din cauza unui script terț de chat care rula re-renderings inutile la fiecare scroll. DevTools îmi dădea scor 96, dar în consola Google Search Console apăreau avertismente cu galben și roșu.

Vercel Speed Insights vs RUM Custom

Dacă ești găzduit pe Vercel, soluția lor integrată (Speed Insights) e extraordinar de comodă. Importi un pachet de react/next, îl pui în root layout și ai terminat. Dashboard-ul oferă direct percentilele P75 pentru LCP, INP și CLS grupate pe rute.

Câștigul e uriaș pe partea de developer experience: zero mentenanță, zero infrastructură de logare. Punctul slab? Ești blocat în ecosistemul lor, iar la volume mari de trafic devine scump. În plus, dacă ai nevoie să corelezi un INP prost cu ID-ul de sesiune din backend sau cu erori din Sentry, opțiunile sunt destul de limitate.

Dacă rulezi pe infrastructură proprie (AWS, Hetzner, Docker), librăria oficială web-vitals de la Google rămâne varianta cea mai curată. Trimiți metricele într-un endpoint propriu de colectare și de acolo le tragi în Grafana sau ClickHouse.

Atenție la raportarea datelor în browser

Când îți scrii propriul script de RUM, cel mai important lucru e cum trimiți datele către server. Nu folosi un fetch obișnuit pe evenimente de unload sau visibilitychange, pentru că browserul îl va anula în jumătate din cazuri.

Trimiterea trebuie făcută exclusiv prin navigator.sendBeacon sau fetch cu opțiunea keepalive: true. Altfel, fix utilizatorii care închid repede pagina din cauză că se blochează nu vor fi numărați, iar datele tale vor arăta fals de bine.

Ce soluții folosiți în prezent pe proiectele de producție? Ați mers pe variantele integrate oferite de platformele de hosting (Vercel, Cloudflare) sau vă strângeți metricele RUM în infrastructura proprie?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.