Guida all’ottimizzazione di INP e dell’interattività delle pagine

Tempo di lettura : 10 minuti

È l’ultima metrica sul campo di Google per le prestazioni web, misura la reattività, in modo simile ma più accurato rispetto al First Input Delay (FID), ed è già candidata a entrare tra i Core Web Vitals: parliamo di INP, Interaction to Next Paint, che misura quanto velocemente la pagina risponde all’input di un utente, ma questa volta ci concentriamo sui consigli per ottimizzare le prestazioni delle nostre pagine e per superare quindi le soglie ottimali di riferimento. Insomma, andiamo a scoprire come intervenire tecnicamente per migliorare la metrica INP e, soprattutto, offrire sempre buone prestazioni per i nostri utenti.

L’importanza della metrica INP

A guidarci verso il raggiungimento di questo obiettivo è l’articolo di Jeremy Wagner e Philip Walton apparso su web.dev, che ci spiegano tutti i dettagli utili su quella che potrebbe diventare una delle metriche chiave anche in ottica SEO e posizionamento.

Anche se definita ancora sperimentale, infatti, INP promette di fornire una molto più accurata della reattività di una pagina rispetto a First Input Delay, perché considera tutte le interazioni della pagina e la latenza completa dell’interazione, mentre FID misura la prima interazione e solo il ritardo di input di tale interazione (con misurazioni pertanto più veloci, dalle soglie inferiori), e quindi non stupirebbe troppo un suo ingresso nel novero dei Core Web Vitals, che come sappiamo sono un fattore di ranking ufficiale per Google, compresi all’interno del Page Experience System.

La metrica INP

È quindi utile iniziare a familiarizzare da subito con questa metrica, ricordando innanzitutto cosa significa e cosa misura prima di approfondire quali sono gli interventi tecnici per ottimizzare le nostre pagine.

Come ricordano Wagner e Walton, Interaction to Next Paint (INP) è una metrica sperimentale che valuta la responsiveness, la reattività complessiva di una pagina alle interazioni dell’utente, osservando la latenza di tutte le interazioni con click, tocco o pressione di un tasto sulla tastiera che si verificano durante la visita di un utente a una pagina. Il valore finale dell’INP corrisponde all’interazione più lunga osservata, ignorando i valori anomali: in pratica, INP parte al tocco e si conclude quando l’utente vede qualcosa di diverso sullo schermo, ricevendo il feedback che la sua interazione ha innescato il cambiamento, e quindi misura quanto velocemente la pagina risponde all’input di un utente.

Per offrire una buona esperienza all’utente, i siti dovrebbero cercare di avere un Interaction to Next Paint di 200 millisecondi o meno; per essere certi di star raggiungendo questo obiettivo per la maggior parte dei nostri utenti, una buona soglia da misurare è il 75° percentile dei caricamenti di pagina, segmentati tra dispositivi mobili e desktop.

A seconda del sito web, le interazioni possono essere poche o nulle – come ad esempio pagine composte prevalentemente da testo e immagini con pochi o nessun elemento interattivo. Al contrario, nel caso di siti web come editor di testo in-browser o giochi, le interazioni possono essere centinaia o addirittura migliaia. In entrambi i casi, se l’INP è elevato, l’esperienza dell’utente è a rischio.

Come ottimizzare INP sulle pagine del sito

Migliorare l’INP richiede tempo e impegno, dicono i Googler, ma la ricompensa è una migliore esperienza utente ed esiste un percorso per migliorare l’INP.

Prima di entrare negli aspetti tecnici, però, è necessaria un’altra premessa: non tutte le interazioni possono essere attribuite a un elemento specifico, e quindi non sempre è facile o possibile individuare l’elemento che causa la latenza. Ciò è dovuto, dice l’articolo, a una limitazione dell’API Event Timing, per cui il target di un evento può essere assente se l’elemento responsabile dell’interazione è stato disconnesso dal DOM o se l’elemento si trova nel DOM ombra (shadow DOM).

Il primo step per migliorare le prestazioni delle nostre pagine è proprio individuare la causa di un INP scadente, cercando di scoprire quali interazioni tendono a essere responsabili dell’INP della pagina, nel totale delle interazioni che gli utenti hanno con la pagina. Per farlo, inizieremo a lavorare sui dati raccolti sul campo e solo successivamente ci affideremo ai test di laboratorio per capire cosa effettivamente rende lenta un’interazione.

I metodi per trovare le interazioni lente sul campo

E quindi, i dati raccolti sul campo dovrebbero essere il primo punto di partenza per trovare le interazioni lente, che provocano un INP scadente. La libreria JavaScript web-vitals è un modo per trovare queste interazioni, grazie soprattutto alla sua capacità di attribuire valori INP a elementi specifici attraverso la sua build di attribuzione, che vediamo qui rappresentata nell’immagine (che, come le altre, proviene sempre dallo stesso articolo).

Snippet del codice per INP

Quando eseguiamo questo frammento di codice (che è un esempio semplicistico di utilizzo della libreria web-vitals) e interagiamo con una pagina, la console potrebbe riportare qualcosa di simile a quanto segue.

Esempio di risposta di interazione

In questo caso, notiamo che l’INP della pagina è dovuto alla pressione di un pulsante del menu di navigazione, che ha richiesto 248 millisecondi. Con 248 millisecondi, l’INP di questa pagina rientra nella categoria “da migliorare”.

Riprodurre le interazioni lente in laboratorio

Una volta individuati sul campo gli elementi responsabili delle interazioni lente, possiamo passare agli strumenti di laboratorio per iniziare a profilarli, usando ad esempio un profilatore di prestazioni come quello disponibile tra i DevTools di Chrome.

Il processo descritto da Wagner e Walton si articola in sei passaggi:

  1. Visitare la pagina che ospita l’interazione che desideriamo testare.
  2. Aprire i DevTools di Chrome premendo Cmd+Option+I (Ctrl+Alt+I su Windows e Linux).
  3. Andare alla scheda Performance di DevTools.
  4. Fare clic sul pulsante di registrazione nell’angolo superiore sinistro del profilatore di prestazioni vuoto per avviare la registrazione.
  5. Testare l’interazione desiderata sulla pagina.
  6. Fare nuovamente clic sul pulsante di registrazione per interrompere la registrazione.

Quando il profilatore si popola di valori, possiamo iniziare a vedere il tipo di lavoro necessario per guidare l’interazione.

Nel profiler sono presenti alcuni indizi utili per individuare il punto in cui si è verificata l’interazione, in particolare nella traccia delle interazioni situata sopra la traccia del thread principale.

Interazione nel performance profiler

La figura mostra un’interazione profilata nel performance profiler di DevTools di Chrome: la traccia delle interazioni riporta una serie di eventi che equivalgono a un’interazione clic e le voci della traccia delle interazioni coprono tutti i task responsabili dell’interazione.

Anche in questo caso, i Googler lanciano un avvertimento: non dobbiamo pensare di essere in grado di riprodurre le condizioni esatte in cui è stato segnalato un INP elevato quando cerchiamo di riprodurre i problemi riscontrati sul campo con strumenti di laboratorio. Sono infatti molti i fattori che possono causare la lentezza delle risposte del dispositivo ed è impossibile replicarli tutti; tuttavia, se alcune interazioni sono costantemente lente per molti utenti, dovrebbe essere possibile riprodurre questi problemi ricorrenti imitando le condizioni comuni a quegli utenti.

Come profilare la pagina in assenza di dati sul campo

Non tutti raccolgono dati sul campo dagli utenti del proprio sito web, anche se Google suggerisce di includere la raccolta di dati sul campo nei nostri “piani di ottimizzazione delle prestazioni a lungo termine”, perché renderà la diagnosi dei problemi molto più semplice. Ad ogni modo, è comunque possibile profilare le pagine e cercare le interazioni che potrebbero essere lente, così da ottimizzare INP.

Il primo passo consiste nel diagnosticare i comuni user flows: ad esempio, se abbiamo uno shop e-Commerce, alcuni comuni flussi utente potrebbero essere l’aggiunta di articoli al carrello, la ricerca di prodotti e il checkout.

Nel testare questi user flows in laboratorio dobbiamo seguire queste indicazioni:

  1. Regolare la CPU a velocità 4x o 6x per rispecchiare più fedelmente le velocità di interazione degli utenti su dispositivi di fascia bassa.
  2. Abilitare l’emulazione mobile e scegliere un dispositivo mobile di fascia bassa. Quando si utilizza l’emulazione mobile in DevTools, la stringa dell’agente utente viene modificata in quella del dispositivo emulato, il che può influire sul modo in cui viene servito il markup della pagina.
  3. Se ne abbiamo la possibilità, prendiamo in considerazione l’acquisto di un telefono Android più economico (come un Moto E) con capacità ridotte e profiliamo le interazioni in laboratorio usando il debug remoto.

Dopo aver valutato i potenziali flussi utente, annotiamo le interazioni più lente per iniziare a capire da dove partire con l’ottimizzazione.

Diagnosticare e gestire il lungo ritardo di input o long input delay

Il ritardo di input (input delay) è la prima fase di un’interazione: è il periodo di tempo che intercorre tra la ricezione dell’azione dell’utente da parte del sistema operativo e l’inizio dell’elaborazione da parte del browser del primo evento generato da quell’input.

Il ritardo di input termina proprio quando iniziano ad essere eseguiti i callback degli eventi per l’interazione.

L’identificazione di input delay nel profiler delle prestazioni di Chrome avviene trovando prima l’inizio di un’interazione nel pannello delle interazioni e quindi cercando il punto in cui inizia l’esecuzione dei callback degli eventi per quell’interazione.

Causa del ritardo di input

In questa immagine, ad esempio, vediamo un ritardo nell’input causato da un task lanciato da un timer di uno script di terze parti, che è in esecuzione mentre l’utente tenta di interagire con la pagina e quindi prolunga il ritardo di input. Il prolungamento del ritardo di input influisce sulla latenza dell’interazione e potrebbe quindi influire sull’INP della pagina.

Ci capiterà sempre di imbatterci in un qualche input delay, dice l’articolo, poiché il sistema operativo impiega sempre un po’ di tempo per passare l’evento di input al browser, ma possiamo avere comunque un certo controllo sulla durata del ritardo dell’input: il segreto è capire se c’è del lavoro in corso sul thread principale che impedisce l’esecuzione dei callback.

La correzione dei ritardi di input lunghi

Quando gli input delay sono eccessivamente lunghi – definiti letteralmente long input delay – peggiorano ovviamente l’esperienza dell’utente, e il processo di correzione del problema dipende dalla situazione in cui ci troviamo.

Ad esempio, se c’è un task first-party dispendioso in termini di risorse che potrebbe influenzare il ritardo di input di un’interazione, la risposta è quadrupla:

  1. Lavorare il meno possibile in tutti i task avviati dal codice.
  2. Spezzare i task più lunghi.
  3. Usare l’API Scheduler per dare priorità alle attività critiche e rinviare quelle non critiche.
  4. Considerare l’uso di isInputPending per verificare se un input dell’utente è in attesa. In caso affermativo, si può passare al thread principale, in modo che i callback degli eventi per quell’input possano essere eseguiti prima di quanto farebbero altrimenti.

Quando è proprio il codice di terze parti a causare problemi, ci sono molte altre cose da considerare, come ad esempio:

  1. Fare un inventario completo di tutti gli script di terze parti del sito web.
  2. Scoprire se la funzionalità di più di uno script di terze parti si sovrappone in modo significativo agli altri.
  3. Eliminare gli script di terze parti ridondanti o di scarso valore.
  4. Mantenere gli script di terze parti rimasti in modo che incidano il meno possibile sulle prestazioni.

Questo è difficile soprattutto perché i JavaScript di terze parti creano un problema proprio in ambito di lavoro; ad esempio, i tag manager rendono molto facile anche per gli impiegati non tecnici di un’azienda di aggiungere script di terze parti senza che i team di sviluppo ne siano a conoscenza.

Il lavoro per ottimizzare le chiamate agli eventi

Il ritardo di input è solo la prima parte di ciò che INP misura, perché dobbiamo anche verificare le callback di eventi che vengono eseguite in risposta a un’interazione dell’utente, che dovrebbero essere completate il più rapidamente possibile – nell’immagine possiamo vedere ad esempio gli event callback eseguiti in risposta a semplice un’interazione con un tap, come mostrato nel profiler delle prestazioni di Chrome DevTools.

Il modo migliore per assicurare che le callback degli eventi vengano eseguite rapidamente è quello di limitare l’esecuzione alla sola logica necessaria per applicare gli aggiornamenti visivi per il fotogramma successivo, rimandando tutto il resto a un’attività successiva.

Ad esempio, immaginiamo di usare un editor di testo che formatta il testo durante la digitazione, ma che aggiorna anche altri aspetti dell’interfaccia utente in risposta a ciò che scriviamo, come il numero di parole, gli errori di ortografia e così via; inoltre, l’applicazione potrebbe aver bisogno di salvare ciò che abbiamo  scritto, in modo che, se usciamo e rientriamo, non perdiamo il lavoro svolto.

In questo caso, ci sono quattro cose che devono accadere in risposta ai caratteri digitati dall’utente. Tuttavia, solo il primo elemento deve essere eseguito prima che venga presentato il frame successivo.

  1. Aggiornare la casella di testo con i caratteri digitati dall’utente e applicare la formattazione richiesta.
  2. Aggiornare la parte dell’interfaccia utente che visualizza il conteggio corrente delle parole.
  3. Eseguire la logica che controlla gli errori di ortografia.
  4. Salvare le modifiche più recenti (localmente o in un database remoto).

Esempio di codice callback event

Il codice per fare ciò potrebbe essere simile a questo mostrato nell’immagine. La visualizzazione seguente, invece, spiega perché il rinvio degli aggiornamenti non critici dopo il fotogramma successivo può ridurre il tempo di elaborazione, e quindi la latenza complessiva dell’interazione.

Effetto del rinvio degli aggiornamenti non critici

Sebbene l’uso di setTimeout() all’interno di una chiamata a requestAnimationFrame() nell’esempio di codice precedente sia un po’ esoterico, si tratta di un modo efficace e trasversale ai browser per garantire che il codice non critico non blocchi il fotogramma successivo.

In futuro, con la standardizzazione e l’implementazione di nuove API di programmazione come scheduler.postTask() e scheduler.yield(), sarà più facile per gli sviluppatori scrivere codice che possa essere automaticamente prioritizzato senza dover conoscere a fondo il ciclo degli eventi del browser.

Ridurre al minimo il ritardo della presentazione (presentation delay)

L’ultima fase di un’interazione è il ritardo di presentazione, che inizia quando i callback degli eventi hanno terminato l’esecuzione e termina quando il browser è in grado di presentare il fotogramma successivo al display dell’utente.

Purtroppo i ritardi di presentazione sono quelli su cui abbiamo meno controllo, ma ci sono alcuni aspetti da tenere d’occhio se notiamo che i fotogrammi vengono ritardati:

  1. Non abusare di requestAnimationFrame() per lavori non legati al rendering. I callback di requestAnimationFrame() vengono eseguiti durante la fase di rendering del ciclo degli eventi e devono essere completati prima che il fotogramma successivo possa essere presentato. Se usiamo requestAnimationFrame() per eseguire operazioni che non comportano modifiche all’interfaccia utente, occorre tenere presente che si potrebbe ritardare il fotogramma successivo.
  2. Fare attenzione ad async e await e alle nostre ipotesi sul loro funzionamento. Solo perché si usano queste funzioni (o le Promises in generale), non significa che il lavoro che fanno non blocchi il rendering. È del tutto possibile che una funzione asincrona – anche se spezza il lavoro in un callback in un’attività separata – possa comunque bloccare il rendering se il browser sceglie di eseguirla prima che venga presentato il fotogramma successivo. Per questo motivo è importante che tutti i task siano brevi.
  3. Fare attenzione ai callback dell’osservatore ResizeObserver. Tali callback vengono eseguiti prima del rendering e possono ritardare la presentazione del fotogramma successivo se il lavoro in essi contenuto è costoso in termini di risorse, come nel caso dei callback di eventi: per evitare questa situazione, si suggerisce di rinviare qualsiasi logica non necessaria al fotogramma successivo.

I casi di interazioni sovrapposte

L’articolo dei Googler si sofferma anche su come le interazioni possano sovrapporsi: ad esempio, se ci sono molte interazioni in un breve periodo, è possibile che il tempo di elaborazione o il ritardo di presentazione di un’interazione sia una fonte di ritardo di input per un’interazione successiva.

Questa immagine ci mostra la visualizzazione tecnica del problema, con due interazioni concomitanti risultanti dal profilatore di prestazioni di DevTools di Chrome: il lavoro di rendering nell’interazione iniziale con il clic causa un ritardo di input per la successiva interazione con la tastiera.

Interazioni sovrapposte

Queste sovrapposizioni sono difficili da diagnosticare sul campo, in parte perché è difficile capire se la fonte di un INP elevato è dovuta a più interazioni che interferiscono tra loro. La cosa migliore per ridurre la scarsa reattività delle interazioni è fare meno lavoro possibile nei callback degli eventi dell’interazione e mantenere sempre brevi i task. Questo aiuta a ridurre la contesa tra le interazioni e dà al thread principale un po’ più di respiro.

L’ottimizzazione di INP richiede persistenza

Il miglioramento dell’INP del sito è un processo iterativo, concludono Jeremy Wagner e Philip Walton: dopo aver risolto un’interazione lenta sul campo, è molto probabile che (soprattutto se il nostro sito web offre tonnellate di interattività) inizieremo a trovare altre interazioni lente che parimenti dovremo ottimizzare.

La chiave per migliorare l’INP è la perseveranza, quindi. Solo con la giusta pazienza sarà possibile, con il tempo, portare la reattività della nostra pagina a un punto in cui gli utenti siano soddisfatti dell’esperienza che offriamo.

È anche probabile che, man mano che sviluppiamo nuove funzionalità per gli utenti, sia necessario seguire lo stesso processo di ottimizzazione delle interazioni specifiche per loro.

Insomma, per ottimizzare INP ci vorrà tempo e impegno, ma si tratta di tempo e impegno ben spesi, promettono i Googler.

TOP