Verso una migliore metrica relativa alla reattività

Scopri le nostre opinioni sulla misurazione della reattività e inviaci un feedback.

Annie Sullivan
Annie Sullivan
Hongbo Song
Hongbo Song
Nicolás Peña Moreno
Nicolás Peña Moreno

Il team delle metriche di velocità di Chrome ci stiamo adoperando per comprendere meglio la velocità con cui le pagine web rispondono all'input degli utenti. Vorremmo condividere alcune idee per migliorare le metriche sulla reattività e ascoltare il tuo feedback.

Questo post affronterà due argomenti principali:

  1. Esamina la nostra attuale metrica di reattività, First Input Delay (FID), e spiega perché abbiamo scelto il FID anziché alcune alternative.
  2. Presenta alcuni miglioramenti che abbiamo preso in considerazione per acquisire meglio la latenza end-to-end dei singoli eventi. L'obiettivo di questi miglioramenti è inoltre acquisire un quadro più olistico della reattività generale di una pagina nel corso del suo ciclo di vita.

Cos'è First Input Delay?

La metrica First Input Delay (FID) misura il tempo necessario al browser per iniziare a elaborare la prima interazione dell'utente su una pagina. In particolare, misura la differenza tra il momento in cui l'utente interagisce con il dispositivo e il momento in cui il browser è effettivamente in grado di iniziare a elaborare i gestori di eventi. Il FID viene misurato solo per tocchi e pressioni dei tasti, il che significa che prende in considerazione solo la prima occorrenza dei seguenti eventi:

  • click
  • keydown
  • mousedown
  • pointerdown (solo se è seguito da pointerup)

Il seguente diagramma illustra il FID:

First Input Delay misura
da quando si verifica un input a quando può essere gestito

Il FID non include il tempo dedicato all'esecuzione di questi gestori di eventi né il lavoro svolto dal browser in seguito per aggiornare la schermata. Misura per quanto tempo il thread principale è stato occupato prima di avere la possibilità di gestire un input. Questo tempo di blocco è generalmente causato da attività JavaScript lunghe, poiché non possono essere arrestate in qualsiasi momento, quindi l'attività corrente deve essere completata prima che il browser possa iniziare a elaborare l'input.

Perché abbiamo scelto FID?

Riteniamo che sia importante misurare l'esperienza utente effettiva per garantire che i miglioramenti apportati alla metrica generino vantaggi reali per l'utente. Abbiamo scelto di misurare il FID perché rappresenta la parte dell'esperienza utente quando l'utente decide di interagire con un sito appena caricato. FID acquisisce una parte del tempo che l'utente deve attendere per vedere una risposta dalla sua interazione con un sito. In altre parole, il FID è un limite inferiore al tempo di attesa di un utente dopo l'interazione.

Altre metriche come Tempo di blocco totale (TBT) e Tempo all'interattività (TTI) si basano su attività lunghe e, come il FID, misura anche il tempo di blocco dei thread principali durante il caricamento. Poiché queste metriche possono essere misurate sia sul campo che in laboratorio, molti sviluppatori ci hanno chiesto perché non preferiamo una di queste metriche al FID.

Ciò per diversi motivi. Forse il motivo più importante è che queste metriche non misurano direttamente l'esperienza utente. Tutte queste metriche misurano la quantità di JavaScript eseguito sulla pagina. Anche se JavaScript a lunga esecuzione tende a causare problemi ai siti, queste attività non influiscono necessariamente sull'esperienza utente se l'utente non interagisce con la pagina quando si verifica. Una pagina può avere un ottimo punteggio per TBT e TTI, ma sembra lenta o può avere un punteggio scarso mentre si sente veloce per gli utenti. In base alla nostra esperienza, queste misurazioni indirette generano metriche molto efficaci per alcuni siti, ma non per la maggior parte dei siti. In breve, il fatto che le attività lunghe e il TTI non siano incentrati sull'utente rende questi candidati più deboli.

Sebbene la misurazione di laboratorio sia sicuramente importante e uno strumento inestimabile per la diagnostica, ciò che conta davvero è l'esperienza degli utenti sui siti. Grazie a una metrica incentrata sugli utenti che riflette le condizioni reali degli utenti, hai la certezza di acquisire qualcosa di significativo nell'esperienza. Abbiamo deciso di iniziare con una piccola parte di questa esperienza, anche se sappiamo che questa parte non è rappresentativa dell'esperienza completa. Questo è il motivo per cui stiamo lavorando per acquisire una porzione maggiore del tempo che un utente attende la gestione dei propri input.

Nota sulla misurazione dell'TTI sul campo

Misurare il TTI su utenti reali del campo è problematico perché si verifica molto tardi nel caricamento della pagina. È necessaria una finestra silenziosa di rete di 5 secondi prima di poter calcolare il TTI. Nel lab, puoi scegliere di annullare il caricamento della pagina ogni volta che hai tutti i dati di cui hai bisogno, ma non è così con il monitoraggio degli utenti reali sul campo. Un utente può scegliere di abbandonare la pagina o di interagirvi in qualsiasi momento. In particolare, gli utenti possono scegliere di abbandonare pagine il cui caricamento richiede molto tempo e in questi casi non viene registrato un TTI accurato. Quando abbiamo misurato il TTI per gli utenti reali in Chrome, abbiamo riscontrato che solo la metà dei caricamenti di pagine ha raggiunto il TTI.

Quali miglioramenti stiamo prendendo in considerazione?

Vorremmo sviluppare una nuova metrica che estenda le misure attuali di FID, pur mantenendo una forte connessione con l'esperienza utente.

La nuova metrica deve:

  1. Considera la reattività di tutti gli input utente (non solo il primo)
  2. Acquisisci l'intera durata di ogni evento (non solo il ritardo).
  3. Raggruppa gli eventi che si verificano nell'ambito della stessa interazione logica dell'utente e definisci la latenza di quell'interazione come la durata massima di tutti i suoi eventi.
  4. Creare un punteggio aggregato per tutte le interazioni che si verificano su una pagina, durante il suo intero ciclo di vita.

Per avere successo, dovremmo essere in grado di affermare con elevata certezza che se un sito ottiene un punteggio basso per questa nuova metrica, non risponde rapidamente alle interazioni degli utenti.

Acquisisci l'intera durata dell'evento

Il primo miglioramento evidente è provare a ottenere una latenza end-to-end più ampia di un evento. Come indicato in precedenza, FID acquisisce solo la parte del ritardo dell'evento di input. Questo non tiene conto del tempo impiegato dal browser per elaborare effettivamente i gestori di eventi.

Esistono varie fasi del ciclo di vita di un evento, come illustrato in questo diagramma:

Cinque passaggi nel ciclo di vita di un evento

Di seguito sono riportati i passaggi seguiti da Chrome per elaborare un input:

  1. Viene restituito l'input dell'utente. L'ora in cui si verifica è l'timeStamp dell'evento.
  2. Il browser esegue test sugli hit per decidere a quale frame HTML (frame principale o iframe) appartiene un evento. Dopodiché il browser invia l'evento al processo di rendering appropriato responsabile di quel frame HTML.
  3. Il renderer riceve l'evento e lo mette in coda per elaborarlo quando diventa disponibile.
  4. Il renderer elabora l'evento eseguendo i propri gestori. Questi gestori possono mettere in coda ulteriori lavori asincroni, come setTimeout e recuperi, che fanno parte della gestione dell'input. A questo punto, però, il lavoro sincrono è completo.
  5. Sullo schermo viene dipinto un frame che riflette il risultato dei gestori di eventi in esecuzione. Tieni presente che tutte le attività asincrone in coda dai gestori di eventi potrebbero essere ancora da completare.

Il tempo tra i passaggi (1) e (3) precedenti rappresenta il ritardo di un evento, ovvero quanto misura FID.

Il tempo che intercorre tra i passaggi (1) e (5) riportati sopra è la durata di un evento. Questo è ciò che verrà misurata dalla nostra nuova metrica.

La durata dell'evento include il ritardo, ma anche il lavoro che si verifica nei gestori di eventi e il lavoro che il browser deve fare per colorare il frame successivo dopo l'esecuzione di questi gestori. La durata di un evento è attualmente disponibile nell'API Event Timing tramite l'attributo duration della voce.

Nota sulle attività asincrone

Idealmente, vorremmo acquisire anche il lavoro asincrono attivato dall'evento. Il problema, però, è che la definizione di lavoro asincrono attivato dall'evento è estremamente difficile da definire. Ad esempio, uno sviluppatore potrebbe scegliere di avviare alcune animazioni dei gestori di eventi e utilizzare un elemento setTimeout per avviarla. Se acquisiamo tutte le attività pubblicate sui gestori, l'animazione ritarda il tempo di completamento finché viene eseguita. Riteniamo che valga la pena esaminare le opzioni di utilizzo dell'euristica per acquisire il lavoro asincrono e che dovrebbe essere completato il prima possibile. Tuttavia, vogliamo essere molto attenti in questa fase, perché non vogliamo penalizzare i lavori il cui completamento richiede molto tempo. Di conseguenza, il nostro sforzo iniziale considererà il passaggio 5 come punto finale: prenderà in considerazione solo il lavoro sincrono e il tempo necessario per dipingere al termine di questo lavoro. In altre parole, non applicheremo l'euristica per indovinare il lavoro che verrebbe avviato in modo asincrono nel passaggio 4 della nostra procedura iniziale.

Vale la pena notare che, in molti casi, il lavoro deve essere eseguito in modo sincrono. Questo potrebbe essere inevitabile perché a volte gli eventi vengono inviati uno dopo l'altro e i gestori di eventi devono essere eseguiti in ordine. Detto questo, continueremo a perdere attività importanti, ad esempio eventi che attivano il recupero o che si basano su operazioni importanti da completare al successivo callback requestAnimationFrame.

Raggruppa gli eventi in interazioni

L'estensione della misurazione della metrica dal ritardo alla durata è un buon primo passo, ma lascia comunque una lacuna fondamentale nella metrica: questo approccio si concentra sui singoli eventi e non sull'esperienza utente derivante dall'interazione con la pagina.

Molti eventi diversi possono attivarsi a seguito di una singola interazione dell'utente e la misurazione separata di ogni evento non consente di avere un quadro chiaro dell'esperienza dell'utente. Vogliamo essere certi che la nostra metrica acquisisca tutto il tempo a disposizione dell'utente per attendere una risposta quando tocca, preme i tasti, scorre e trascina nel modo più accurato possibile. Per questo motivo, stiamo introducendo il concetto di interazioni per misurare la latenza di ognuna.

Tipo di interazione

Nella tabella seguente sono elencate le quattro interazioni da definire insieme agli eventi DOM a cui sono associati. Tieni presente che non è identico all'insieme di tutti gli eventi che vengono inviati quando si verifica l'interazione dell'utente. Ad esempio, quando un utente scorre, viene inviato un evento di scorrimento, che però si verifica dopo che la schermata è stata aggiornata in modo da riflettere lo scorrimento. Pertanto, non lo consideriamo parte della latenza dell'interazione.

Interazione Inizio / fine Eventi desktop Eventi mobile
Tastiera Tasto premuto keydown keydown
keypress keypress
Chiave rilasciata keyup keyup
Tocca o trascina Tocca Avvia o trascina l'inizio pointerdown pointerdown
mousedown touchstart
Tocca verso l'alto o trascina la fine pointerup pointerup
mouseup touchend
click mousedown
mouseup
click
Scorri N/A
Eventi DOM per ogni tipo di interazione.

Le prime tre interazioni elencate in precedenza (tastiera, tocco e trascinamento) sono attualmente coperte da FID. Per la nostra nuova metrica relativa alla reattività, vogliamo includere anche lo scorrimento, poiché lo scorrimento è estremamente comune sul web ed è un aspetto fondamentale del livello di reattività di una pagina agli utenti.

Una nota all'inizio e alla fine

Tieni presente che ciascuna di queste interazioni si compone di due parti: quando l'utente preme il mouse, il dito o il tasto giù e quando lo solleva. Dobbiamo assicurarci che la nostra metrica non conti il tempo che l'utente trascorre tenendo il dito tra queste due azioni come parte della latenza della pagina.

Tastiera

L'interazione da tastiera è composta da due parti: quando l'utente preme il tasto e quando lo rilascia. A questa interazione utente sono associati tre eventi: keydown, keyup e keypress. Il seguente diagramma illustra i ritardi e le durate di keydown e keyup per un'interazione da tastiera:

Interazione da tastiera
con durate di eventi non comprese

Nel diagramma precedente, le durate sono separate perché il frame degli aggiornamenti di keydown viene presentato prima che si verifichi keyup, ma non è necessario che sia sempre così. Inoltre, tieni presente che un frame può essere presentato nel bel mezzo di un'attività nel processo di rendering, poiché gli ultimi passaggi necessari per produrre il frame vengono eseguiti al di fuori di questo processo.

keydown e keypress si verificano quando l'utente preme il tasto, mentre keyup si verificano quando l'utente rilascia il tasto. In genere l'aggiornamento dei contenuti principali si verifica quando viene premuto il tasto: viene visualizzato del testo sullo schermo o viene applicato l'effetto di modifica. Detto questo, vogliamo acquisire i casi più rari in cui keyup presenterebbe anche interessanti aggiornamenti dell'interfaccia utente, quindi vogliamo esaminare il tempo complessivo.

Per acquisire il tempo complessivo impiegato dall'interazione da tastiera, possiamo calcolare la durata massima degli eventi keydown e keyup.

Nota sulla ripetizione della pressione dei tasti

C'è un caso limite qui che vale la pena menzionare: in alcuni casi l'utente potrebbe premere un tasto e impiegare un po' di tempo per rilasciarlo. In questo caso, la sequenza degli eventi inviati può variare. In questi casi, viene presa in considerazione una sola interazione per keydown, che può avere o meno un valore keyup corrispondente.

Tocca

Un'altra interazione importante dell'utente è quando l'utente tocca o fa clic su un sito web. Come nel caso di keypress, alcuni eventi vengono attivati quando l'utente preme verso il basso e altri quando vengono rilasciati, come mostrato nel diagramma in alto. Tieni presente che gli eventi associati a un tocco sono leggermente diversi su computer desktop e dispositivi mobili.

Per un tocco o un clic, la release è generalmente quella che attiva la maggior parte delle reazioni. Tuttavia, come per le interazioni da tastiera, vogliamo acquisire l'intera interazione. In questo caso è più importante farlo perché avere aggiornamenti dell'interfaccia utente al momento della pressione del tocco non è poi così raro.

Vorremmo includere la durata di tutti questi eventi, ma poiché molti di loro si sovrappongono completamente, dobbiamo misurare solo pointerdown, pointerup e click per coprire l'intera interazione.

Possiamo restringere ulteriormente l'ambito solo per pointerdown e pointerup?

Inizialmente, dovresti utilizzare gli eventi pointerdown e pointerup e presumere che coprano tutte le durate che ci interessano. Purtroppo, non è così, come mostra questo caso limite. Prova ad aprire questo sito da un dispositivo mobile o con l'emulazione di un dispositivo mobile e tocca il punto in cui è visualizzato il messaggio "Fai clic qui". Questo sito attiva il ritardo di tocco del browser. Si può notare che pointerdown, pointerup e touchend vengono spediti rapidamente, mentre mousedown, mouseup e click attendono il ritardo prima di essere spediti. Ciò significa che se guardassimo solo pointerdown e pointerup, perderemmo la durata degli eventi sintetici, che è elevata a causa del ritardo di tocco del browser e dovrebbe essere inclusa. Dovremmo quindi misurare pointerdown, pointerup e click per coprire l'intera interazione.

Resistenza aerodinamica

Abbiamo deciso di includere anche il trascinamento poiché ha eventi associati simili e poiché in genere causa importanti aggiornamenti dell'interfaccia utente per i siti. Per la metrica, invece, prendiamo in considerazione solo l'inizio e la fine del trascinamento, ovvero le parti iniziali e finali. Ciò consente di ragionare più facilmente e di rendere le latenze paragonabili alle altre interazioni prese in considerazione. Ciò è in linea con la nostra decisione di escludere gli eventi continui come mouseover.

Inoltre, non stiamo prendendo in considerazione l'implementazione dei trascinamenti tramite l'API di trascinamento perché funzionano solo su computer.

Scorrimento

Una delle forme più comuni di interazione con un sito è lo scorrimento. Per la nostra nuova metrica, vorremmo misurare la latenza per l'interazione iniziale dello scorrimento da parte dell'utente. In particolare, indichiamo la reazione iniziale del browser alla richiesta di scorrimento da parte dell'utente. Non tratteremo l'intera esperienza di scorrimento. In altre parole, lo scorrimento genera molti frame e concentreremo la nostra attenzione sul fotogramma iniziale prodotto come reazione allo scorrimento.

Perché solo il primo? Per uno, i frame successivi possono essere acquisiti da una proposta di fluidità separata. In altre parole, una volta che all'utente viene mostrato il primo risultato dello scorrimento, il resto deve essere misurato in termini di quanto sia fluida l'esperienza di scorrimento. Riteniamo quindi che lo sforzo di fluidità potrebbe rappresentare meglio la situazione. Quindi, come per FID, scegliamo di attenerti a esperienze utente discrete: esperienze utente associate a periodi di tempo chiari e per i quali possiamo calcolare facilmente la latenza. Lo scorrimento nel suo complesso è un'esperienza continua, quindi non intendiamo misurarla tutti in questa metrica.

Perché misurare gli scorrimenti? Le prestazioni di scorrimento che abbiamo raccolto in Chrome mostrano che lo scorrimento è generalmente molto veloce. Detto questo, vogliamo comunque includere le latenze di scorrimento iniziali nella nuova metrica per vari motivi. Primo, lo scorrimento è veloce solo perché è stato ottimizzato molto perché è molto importante. Ci sono però ancora dei modi per un sito web per aggirare alcuni dei miglioramenti in termini di prestazioni offerti dal browser. Il più comune in Chrome è la necessità di forzare lo scorrimento nel thread principale. Pertanto, la nostra metrica dovrebbe essere in grado di dire quando ciò si verifica e causa uno scarso rendimento dello scorrimento per gli utenti. Secondo, lo scorrimento è troppo importante per essere ignorato. Temiamo che, se escludiamo lo scorrimento, possiamo avere un grande punto cieco e le prestazioni dello scorrimento potrebbero diminuire nel tempo senza che gli sviluppatori web se ne accorgano.

Esistono diversi eventi che vengono inviati quando un utente scorre, ad esempio touchstart, touchmove e scroll. Ad eccezione dell'evento di scorrimento, questo dipende in gran parte dal dispositivo utilizzato per lo scorrimento: gli eventi tocco vengono inviati quando si scorre con il dito sui dispositivi mobili, mentre gli eventi rotellina si verificano quando si scorre con la rotellina del mouse. Gli eventi di scorrimento vengono attivati al termine dello scorrimento iniziale. In generale, nessun evento DOM blocca lo scorrimento, a meno che il sito web non utilizzi Listener di eventi non passivi. Lo scorrimento è quindi disaccoppiato dagli eventi DOM. Quello che vogliamo misurare è il tempo che intercorre tra il momento in cui l'utente si muove abbastanza da produrre un gesto di scorrimento fino al primo frame che mostra che è avvenuto lo scorrimento.

Come definire la latenza di un'interazione?

Come indicato in precedenza, le interazioni che presentano un componente "basso" e "in alto" devono essere considerate separatamente per evitare di attribuire il tempo che l'utente ha passato tenendo il dito premuto.

Per questi tipi di interazioni, vorremmo che la latenza coinvolga la durata di tutti gli eventi associati. Poiché le durate degli eventi per ogni parte "in alto" e in "basso" dell'interazione possono sovrapporsi, la definizione più semplice di latenza di interazione che raggiunge questa è la durata massima di qualsiasi evento associato. Tornando al diagramma della tastiera di cui sopra, questa è la durata di keydown, in quanto è più lunga di keyup:

Interazione da tastiera
con la durata massima evidenziata

Le durate di keydown e keyup potrebbero sovrapporsi. Questo può accadere, ad esempio, quando il frame presentato per entrambi gli eventi è lo stesso, come nel seguente diagramma:

Interazione con la tastiera, in cui
la pressione e il rilascio avvengono nello stesso frame

Questo approccio comporta l'utilizzo del massimo numero di vantaggi e svantaggi. Apprezziamo il tuo feedback:

  • Pro: è in linea con il modo in cui intendiamo misurare lo scorrimento, in quanto misura solo un valore di durata singolo.
  • Pro: mira a ridurre il rumore per casi come le interazioni da tastiera, dove di solito keyup non fa nulla e l'utente può premere e rilasciare il tasto rapidamente o lentamente.
  • Svantaggio: non cattura il tempo di attesa completo dell'utente. Ad esempio, acquisisce l'inizio o la fine di un trascinamento, ma non entrambi.

Per lo scorrimento (che ha un solo evento associato) vorremmo definire la latenza come il tempo necessario al browser per produrre il primo frame dopo lo scorrimento. In altre parole, la latenza è il delta tra l'evento timeStamp del primo evento DOM (come touchmove, se si utilizza un dito), abbastanza grande da attivare uno scorrimento e la prima visualizzazione che riflette lo scorrimento in corso.

Aggrega tutte le interazioni per pagina

Una volta definita la latenza di un'interazione, dobbiamo calcolare un valore aggregato per il caricamento di una pagina, che potrebbe causare molte interazioni da parte degli utenti. Avere un valore aggregato ci consente di:

  • Correlazioni dei moduli con le metriche aziendali.
  • Valutare le correlazioni con altre metriche delle prestazioni. Idealmente, la nuova metrica sarà sufficientemente indipendente da aggiungere valore a quelle esistenti.
  • Esponi facilmente i valori negli strumenti in modo che siano facili da assimilare.

Per eseguire questa aggregazione dobbiamo rispondere a due domande:

  1. Quali numeri proviamo ad aggregare?
  2. Come facciamo ad aggregare questi dati?

Stiamo valutando e valutando diverse opzioni. Apprezziamo la tua opinione su questa aggregazione.

Un'opzione è definire un budget per la latenza di un'interazione, che può dipendere dal tipo (scorrimento, tastiera, tocco o trascinamento). Ad esempio, se il budget per le tocchi è 100 ms e la latenza di un tocco è 150 ms, l'importo oltre il budget per quell'interazione sarebbe di 50 ms. In questo modo potremmo calcolare la latenza massima che supera il budget per qualsiasi interazione dell'utente nella pagina.

Un'altra opzione è calcolare la latenza media o mediana delle interazioni in tutta la durata della pagina. Pertanto, con latenze di 80 ms, 90 ms e 100 ms, la latenza media della pagina sarebbe di 90 ms. Potremmo anche considerare la media o la mediana "oltre il budget" per tenere conto di aspettative diverse in base al tipo di interazione.

Come si presenta sulle API Web Performance?

Che cosa manca in Tempi eventi?

Purtroppo, non tutte le idee presentate in questo post possono essere acquisite utilizzando l'API Event Timing. In particolare, non esiste un modo semplice per conoscere gli eventi associati a una determinata interazione dell'utente con l'API. A questo scopo, abbiamo proposto l'aggiunta di un interactionID all'API.

Un'altra lacuna dell'API Event Timing è che non è possibile misurare l'interazione di scorrimento, perciò stiamo attivando queste misurazioni (tramite Event Timing o un'API separata).

Cosa puoi provare ora?

Attualmente è ancora possibile calcolare la latenza massima per tocchi/trascinamenti e per le interazioni da tastiera. Il seguente snippet di codice produrrebbe queste due metriche.

let maxTapOrDragDuration = 0;
let maxKeyboardDuration = 0;
const observer = new PerformanceObserver(list => {
  list.getEntries().forEach(entry => {
    switch(entry.name) {
      case "keydown":
      case "keyup":
        maxKeyboardDuration = Math.max(maxKeyboardDuration,
            entry.duration);
        break;
      case "pointerdown":
      case "pointerup":
      case "click":
        maxTapOrDragDuration = Math.max(maxTapOrDragDuration,
            entry.duration);
        break;
    }
  });
});
observer.observe({type: "event", durationThreshold: 16, buffered: true});
// We can report maxTapDragDuration and maxKeyboardDuration when sending
// metrics to analytics.

Feedback

Facci sapere cosa pensi di queste idee inviando un'email a: web-vitals-feedback@googlegroups.com!