Ottimizza ritardo input

Scopri cos'è il ritardo di input e impara tecniche per ridurlo per un'interattività più rapida.

Le interazioni sul web sono cose complicate, perché nel browser si verificano qualsiasi tipo di attività per guidarle. Tuttavia, tutti hanno in comune il fatto che subiscono un ritardo nell'input prima che inizi l'esecuzione dei callback degli eventi. In questa guida scoprirai cos'è il ritardo di input e cosa puoi fare per ridurlo al minimo in modo che le interazioni sul tuo sito web vengano eseguite più velocemente.

Che cos'è il ritardo di input?

Il ritardo input è il periodo di tempo che va dal momento in cui l'utente interagisce per la prima volta con una pagina, ad esempio toccando uno schermo, facendo clic con il mouse o premendo un tasto, fino al momento in cui inizia l'esecuzione del callback dell'evento per l'interazione. Ogni interazione inizia con un certo ritardo nell'input.

Una visualizzazione semplificata del ritardo di input. A sinistra è presente il disegno di un cursore del mouse con dietro una serie di stelle, che indica l'inizio di un'interazione. A destra si vede il disegno di una ruota dentata, che indica l'inizio dell'esecuzione dei gestori di eventi di un'interazione. Lo spazio tra le parentesi graffe viene indicato come ritardo di input.
I meccanismi alla base del ritardo di input. Quando il sistema operativo riceve un input, questo deve essere trasmesso al browser prima che l'interazione abbia inizio. Questa operazione richiede un certo tempo e può essere aumentata dal lavoro del thread principale esistente.

Una parte del ritardo nell'input è inevitabile: il sistema operativo impiega sempre un po' di tempo per riconoscere un evento di input e passarlo al browser. Tuttavia, quella parte del ritardo di input spesso non è neanche percepibile e ci sono altri eventi che si verificano nella pagina stessa che possono causare ritardi nell'input abbastanza lunghi da causare problemi.

Come considerare il ritardo di input

In generale, vuoi che ogni parte di un'interazione sia il più breve possibile, in modo che il tuo sito web abbia le migliori probabilità di soddisfare la soglia "valida" della metrica "Interaction to Next Paint (INP)", indipendentemente dal dispositivo dell'utente. Mantenere un ritardo nell'input è solo una parte del raggiungimento di questa soglia.

Di conseguenza, ti consigliamo di cercare il ritardo di input più breve possibile per raggiungere la soglia "buona" di INP. Tuttavia, tieni presente che non puoi aspettarti di eliminare del tutto i ritardi di input. Se stai evitando un lavoro eccessivo del thread principale mentre gli utenti tentano di interagire con la tua pagina, il ritardo di input dovrebbe essere abbastanza basso da evitare problemi.

Come ridurre al minimo il ritardo di input

Come detto in precedenza, un certo ritardo nell'ingresso è inevitabile, ma invece è evitabile. Di seguito sono riportati alcuni aspetti da considerare in caso di lunghi ritardi di input.

Evita timer ricorrenti che causano l'avvio eccessivo del thread principale

Esistono due funzioni timer di uso comune in JavaScript che possono contribuire al ritardo di input: setTimeout e setInterval. La differenza tra i due è che setTimeout pianifica l'esecuzione di un callback dopo un determinato orario. setInterval, invece, pianifica un callback da eseguire ogni n millisecondi senza interruzioni o fino a quando il timer non viene interrotto con clearInterval.

setTimeout di per sé non è problematico, anzi può essere utile per evitare attività lunghe. Tuttavia, dipende da quando si verifica il timeout e dal fatto che l'utente provi a interagire con la pagina durante l'esecuzione del callback di timeout.

Inoltre, setTimeout può essere eseguito in loop o in modo ricorsivo, dove agisce più come setInterval, anche se preferibilmente non pianifica l'iterazione successiva fino al completamento di quella precedente. Anche se questo significa che il loop cederà al thread principale ogni volta che viene chiamato setTimeout, dovresti assicurarti che il callback non finisca per svolgere un lavoro eccessivo.

setInterval esegue un callback in base a un intervallo, pertanto è molto più probabile che interferisca con le interazioni. Questo perché, a differenza di una singola istanza di una chiamata setTimeout, che è un callback una tantum che potrebbe intralciare un'interazione utente, la natura ricorrente di setInterval aumenta le probabilità che sia un ostacolo a un'interazione, aumentando così il ritardo di input dell'interazione.

Uno screenshot del profiler delle prestazioni in Chrome DevTools che mostra il ritardo di input. Un'attività attivata da una funzione timer si verifica subito prima che un utente avvii un'interazione con clic. Tuttavia, il timer estende il ritardo di input, causando l'esecuzione dei callback degli eventi dell'interazione più tardi del previsto.
Un timer registrato da una chiamata setInterval precedente che contribuisce al ritardo di input come illustrato nel riquadro delle prestazioni di Chrome DevTools. L'aggiunta di un ritardo di input fa sì che i callback dell'evento vengano eseguiti più tardi del previsto.

Se i timer vengono eseguiti con codice proprietario, sei tu ad avere il controllo su di essi. Valuta se ne hai bisogno o fai del tuo meglio per ridurre il più possibile il lavoro al loro interno. Tuttavia, i timer negli script di terze parti sono diversi. Spesso non hai il controllo sulle azioni di uno script di terze parti e la risoluzione dei problemi di prestazioni nel codice di terze parti spesso comporta la collaborazione con gli stakeholder per determinare se è necessario uno script di terze parti e, in tal caso, stabilire un contatto con un fornitore di script di terze parti per determinare cosa è possibile fare per risolvere i problemi di prestazioni che potrebbero causare sul tuo sito web.

Evita attività lunghe

Un modo per ridurre lunghi ritardi nell'input è evitare attività lunghe. Se il lavoro del thread principale è eccessivo durante le interazioni, questo si aggiunge al ritardo di input prima che le attività lunghe vengano completate.

Una visualizzazione del tempo per cui le attività estendono il ritardo di input. In alto, un'interazione si verifica poco dopo l'esecuzione di una singola lunga attività, causando un ritardo significativo nell'input e con conseguente esecuzione dei callback degli eventi molto più tardi del previsto. In fondo, un'interazione avviene più o meno contemporaneamente, ma l'attività lunga viene suddivisa in diverse attività più piccole, ottenendo così un'esecuzione molto più rapida dei callback degli eventi dell'interazione.
Una visualizzazione di cosa succede alle interazioni quando le attività sono troppo lunghe e il browser non è in grado di rispondere abbastanza rapidamente alle interazioni, rispetto a quando le attività più lunghe vengono suddivise in attività più piccole.

Oltre a ridurre al minimo la quantità di lavoro da svolgere in un'attività (e dovresti sempre cercare di lavorare il meno possibile sul thread principale), puoi migliorare la reattività all'input dell'utente suddividendo attività lunghe.

Fai attenzione alla sovrapposizione delle interazioni

Una parte particolarmente impegnativa dell'ottimizzazione dell'INP può essere rappresentata dalla presenza di interazioni che si sovrappongono. La sovrapposizione delle interazioni significa che, dopo aver interagito con un elemento, effettui un'altra interazione con la pagina prima che l'interazione iniziale abbia avuto la possibilità di visualizzare il frame successivo.

Una rappresentazione del momento in cui le attività possono sovrapporsi per produrre lunghi ritardi nell'input. In questa illustrazione, un'interazione di clic si sovrappone a un'interazione di keydown per aumentare il ritardo di input per l'interazione keydown.
Una visualizzazione di due interazioni simultanee nel profiler delle prestazioni in DevTools di Chrome. Il lavoro di rendering nell'interazione con il clic iniziale causa un ritardo di input per la successiva interazione da tastiera.

Le cause di sovrapposizione delle interazioni possono essere semplici, come le interazioni degli utenti in un breve periodo di tempo. Questo può verificarsi quando gli utenti digitano nei campi del modulo, dove possono verificarsi molte interazioni da tastiera in un periodo di tempo molto breve. Se il lavoro su un evento chiave è particolarmente costoso, ad esempio nel caso comune dei campi di completamento automatico in cui le richieste di rete vengono effettuate a un backend, hai due opzioni:

  • Valuta la possibilità di eseguire il debouncing degli input per limitare il numero di volte in cui il callback di un evento viene eseguito in un determinato periodo di tempo.
  • Utilizza AbortController per annullare le richieste fetch in uscita in modo che il thread principale non diventi congestionato durante la gestione dei callback fetch. Nota: la proprietà signal di un'istanza AbortController può essere utilizzata anche per interrompere gli eventi.

Un'altra causa di un aumento del ritardo di input dovuto a interazioni sovrapposte può essere le animazioni costose. In particolare, le animazioni in JavaScript possono attivare molte chiamate a requestAnimationFrame, che potrebbero interferire con le interazioni degli utenti. Per aggirare questo problema, se possibile utilizza le animazioni CSS per evitare di mettere in coda frame di animazione potenzialmente costosi; in questo caso, però, assicurati di evitare le animazioni non composte, in modo che le animazioni vengano eseguite principalmente sui thread della GPU e del compositore e non sul thread principale.

Conclusione

È possibile che i ritardi nell'inserimento non rappresentino la maggior parte del tempo necessario per l'esecuzione delle interazioni, ma è importante capire che ogni parte di un'interazione richiede un tempo che puoi ridurre. Se risconti un lungo ritardo nell'input, hai la possibilità di ridurlo. Evitare di richiamare i timer ricorrenti, suddividere attività lunghe e prestare attenzione alla potenziale sovrapposizione di interazioni può aiutarti a ridurre il ritardo di input, determinando un'interattività più rapida per gli utenti del tuo sito web.

Immagine hero di Unsplash, di Erik Mclean.