⚡ Prestazioni web

RUM fatto in casa: PerformanceObserver e la libreria web-vitals

Come raccogliere LCP, INP e CLS dagli utenti reali con PerformanceObserver e web-vitals, inviarli in modo affidabile e analizzarli per percentili.

I test di laboratorio dicono come si comporta una pagina in condizioni controllate; il monitoraggio degli utenti reali, o RUM (Real User Monitoring), dice come si comporta davvero sui dispositivi e sulle reti dei visitatori. Esistono servizi commerciali che lo offrono, ma un sistema di base si costruisce con poche righe di codice e un endpoint che riceve i dati. Il vantaggio è il controllo completo: si sceglie cosa raccogliere, dove conservarlo e come incrociarlo con le informazioni del proprio sito.

Le API del browser

Il cuore del RUM è PerformanceObserver, un'interfaccia che notifica al codice le voci di prestazione man mano che il browser le registra. Ogni tipo di voce corrisponde a un fenomeno diverso:

Tipo di voce Cosa descrive
navigation Tempi di caricamento del documento, compreso il TTFB
resource Tempi di ogni risorsa scaricata
largest-contentful-paint Candidati all'elemento più grande disegnato
layout-shift Singoli spostamenti di layout
event Durata delle interazioni, base dell'INP
long-animation-frame Fotogrammi lenti con l'attribuzione degli script

Un esempio diretto per l'LCP:

new PerformanceObserver((elenco) => {
  const voci = elenco.getEntries();
  const ultima = voci[voci.length - 1];
  console.log('LCP candidato:', ultima.startTime, ultima.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });

L'opzione buffered: true recupera anche le voci registrate prima che l'osservatore venisse creato, il che permette di caricare lo script di misura in modo asincrono senza perdere dati.

Perché usare la libreria web-vitals

Calcolare le metriche correttamente è più difficile di quanto sembri. L'LCP va fermato alla prima interazione dell'utente; il CLS si calcola per finestre di sessione, non come semplice somma; l'INP richiede di raggruppare gli eventi per interazione e scegliere un valore vicino al peggiore; le pagine ripristinate dalla bfcache o aperte in background vanno trattate a parte.

La libreria web-vitals, mantenuta dal team di Chrome, implementa tutte queste regole nello stesso modo usato dagli strumenti ufficiali. Il suo utilizzo è semplice:

import { onLCP, onINP, onCLS, onTTFB } from 'web-vitals';

function invia(metrica) {
  const dati = JSON.stringify({
    nome: metrica.name,
    valore: metrica.value,
    valutazione: metrica.rating,
    id: metrica.id,
    pagina: location.pathname,
  });
  navigator.sendBeacon('/rum', dati);
}

onLCP(invia);
onINP(invia);
onCLS(invia);
onTTFB(invia);

Le funzioni non restituiscono il valore subito: lo comunicano quando è definitivo, di solito quando la pagina viene nascosta. Per questo l'invio usa sendBeacon, che completa la richiesta anche se la scheda viene chiusa.

La versione con attribuzione

Sapere che l'INP è alto non basta: bisogna sapere perché. La libreria offre una versione con attribuzione che aggiunge dettagli diagnostici: per l'LCP l'elemento coinvolto e la suddivisione del tempo nelle sue fasi, per l'INP il selettore dell'elemento su cui è avvenuta l'interazione e le tre componenti della latenza, per il CLS l'elemento che si è spostato di più. Sono le informazioni che trasformano un numero in un intervento concreto.

Arricchire i dati

Una metrica isolata dice poco. Conviene allegare a ogni invio alcune dimensioni utili:

  • tipo di pagina (home, scheda prodotto, articolo), più utile del singolo URL;
  • tipo di dispositivo, ricavabile dalla larghezza dello schermo;
  • tipo di navigazione: caricamento normale, ricarica, ritorno dalla bfcache, prerender;
  • qualità della connessione, dove l'API Network Information è disponibile;
  • versione del sito, per confrontare prima e dopo un rilascio.

Attenzione a non raccogliere dati personali: indirizzi IP completi, parametri dell'URL con identificativi o testi digitati non servono alla misura delle prestazioni.

Analizzare per percentili

I valori di prestazione non seguono una distribuzione simmetrica: la maggior parte delle visite è veloce, ma una coda di visite lente può essere molto lunga. La media nasconde questa coda, ed è per questo che i Core Web Vitals si valutano al 75° percentile: il valore sotto il quale cade il 75% delle visite.

Un'analisi utile prevede:

  1. il 75° percentile di ogni metrica per tipo di pagina e dispositivo;
  2. la distribuzione nelle tre fasce: buono, da migliorare, scarso;
  3. l'andamento nel tempo, per notare regressioni dopo un rilascio;
  4. per le pagine peggiori, gli elementi più frequenti nei dati di attribuzione.

Con un database che accetti query SQL, queste viste si costruiscono con poche interrogazioni. Nel mio lavoro, un sistema di RUM minimo ha spesso rivelato problemi invisibili in laboratorio, come un banner che spostava il layout solo su certi modelli di telefono.

Campionare

Su siti molto visitati non serve raccogliere ogni visita. Decidere a inizio pagina, con una probabilità fissa, se la sessione verrà misurata riduce il volume dei dati mantenendo statistiche affidabili. L'importante è che la decisione valga per l'intera visita, non per singola metrica.

In sintesi

  • PerformanceObserver espone le voci di prestazione registrate dal browser.
  • La libreria web-vitals calcola LCP, INP e CLS con le stesse regole degli strumenti ufficiali.
  • Invia i dati con sendBeacon e usa la versione con attribuzione per capire le cause.
  • Arricchisci le misure con tipo di pagina, dispositivo e tipo di navigazione, senza dati personali.
  • Analizza il 75° percentile e l'andamento nel tempo, non la media.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche