INP Processing Time: cause, ottimizzazione ed esempi di codice
Scopri come individuare e migliorare i problemi di INP causati dal processing time

Problemi di Interaction to Next Paint (INP) causati dal processing time
Questa pagina fa parte della nostra serie su Interaction to Next Paint (INP). L'INP misura il tempo totale dall'interazione dell'utente al successivo aggiornamento visivo. Il processing time è la seconda delle tre fasi che compongono l'INP, preceduta dall'input delay e seguita dalla presentation delay. Se non conosci ancora l'INP, leggi prima la nostra guida su come identificare e risolvere i problemi di INP.
In questo articolo ci concentriamo sul processing time: come influisce sull' Interaction to Next Paint e come minimizzare il processing time per migliorare l'INP.
In breve: l'Interaction to Next Paint (INP) misura quanto tempo impiega un utente per vedere un cambiamento visivo su una pagina dopo aver interagito con essa. L'INP può essere suddiviso in 3 componenti: "input delay", "processing time" e "presentation delay".
Il processing time è un contributore significativo all'INP totale, rappresentando in media circa il 40% del ritardo. Questo significa che ottimizzare il codice JavaScript, in particolare gli event handler, può avere un impatto significativo sul punteggio INP del tuo sito web.
SUGGERIMENTO INP: il processing time può essere ottimizzato eseguendo immediatamente il codice importante che precede l'aggiornamento del layout e pianificando l'esecuzione di tutto il resto del codice successivamente.
Table of Contents!
- Problemi di Interaction to Next Paint (INP) causati dal processing time
- Cos'è il processing time?
- Il processing time e l'INP
- Quali sono le cause di un processing time elevato?
- Minimizzare il processing time
- Suddividere gli event handler con setTimeout(0)
- Usare requestAnimationFrame per gli aggiornamenti visivi
- Come dare priorità al codice critico
- Pianificazione granulare con scheduler.postTask()
- Implicazioni pratiche
- Esplora le altre fasi dell'INP
Cos'è il processing time?

L'Interaction to Next Paint (INP) può essere suddiviso in 3 sotto-parti: "Input Delay", "Processing Time" e "Presentation Delay".
Il processing time si riferisce al tempo necessario al browser per eseguire tutti i callback degli eventi associati dopo che un utente interagisce con una pagina web (ad esempio, cliccando un pulsante o premendo un tasto). Sebbene ci sia sempre un certo processing time, i problemi di INP si verificano quando i callback degli eventi richiedono troppo processing time.
Per dirla in modo semplice: il processing time è la durata del "lavoro" che avviene in risposta alla tua interazione. Quando clicchi su un pulsante di ricerca, il processing time include tutto: dalla validazione della query, alla preparazione della richiesta API, all'aggiornamento dello stato locale, all'attivazione degli eventi di analytics e qualsiasi altro codice associato a quell'evento click. Ogni riga di JavaScript in quegli event handler contribuisce al processing time.
Il processing time e l'INP
Il processing time potrebbe essere la prima cosa che viene in mente quando si pensa all'ottimizzazione dell'Interaction to Next Paint. È il "lavoro che deve essere fatto" prima che il layout possa essere aggiornato dal browser.
Molti sviluppatori pensano di migliorare l'INP in termini di ottimizzazione delle funzioni callback (ottimizzando il processing time), e hanno ragione. Ma in termini di importanza, il processing time non è nemmeno la singola parte più importante da migliorare. In media, rappresenta comunque circa il 40% del tempo totale dell'INP.

In CoreDash raccogliamo milioni di data point di Core Web Vitals ogni ora. Sulla base di questi dati, il processing time rappresenta il 40% dell'Interaction to Next Paint. Sebbene sia una porzione significativa, ottimizzare solo il processing time molto probabilmente non sarà sufficiente per risolvere i problemi di INP. Dovresti anche esaminare l'input delay (18%) e la presentation delay (42%).
Esempio di processing time: quando un utente clicca un pulsante per inviare un modulo, il codice che valida i dati del modulo, li invia al server e gestisce la risposta contribuisce tutto al processing time. Più queste operazioni richiedono tempo, più lungo è il processing time e potenzialmente peggiore il punteggio INP.
Quali sono le cause di un processing time elevato?
Per iniziare a risolvere i problemi di INP causati da un processing time elevato, dobbiamo capire quali sono le possibili cause. Un processing time elevato, il tempo necessario ai callback degli eventi per completare l'esecuzione, può essere causato da codice non necessario, codice non ottimizzato, callback raggruppati e layout thrashing. Esaminiamo ciascuna di queste quattro aree.

- Codice non necessario. Codice vecchio, inutilizzato o senza rilevanza immediata per l'interazione dell'utente può prolungare il tempo di esecuzione del callback. Questo include chiamate di analytics, logging e sincronizzazione dello stato che non devono necessariamente completarsi prima del prossimo paint.
- Codice non ottimizzato. Il codice inefficiente (solitamente cicli o ricerche DOM inefficienti) può rendere i callback degli eventi più lenti del necessario. Un esempio comune è interrogare il DOM all'interno di un ciclo con
document.querySelectorAll()invece di memorizzare il risultato in cache prima del ciclo. - Callback raggruppati. Più callback di eventi pianificati ravvicinati creano una coda. Se un callback attivato dall'interazione dell'utente rimane bloccato in questa coda, la risposta appare ritardata. Ad esempio, un handler
pointerdown, un handlermousedowne un handlerclickpossono tutti essere eseguiti in sequenza per un singolo click. - Layout thrashing. Manipolazioni frequenti del DOM che attivano ricalcoli del layout possono sovraccaricare il browser e portare a regressioni delle prestazioni. Questo accade quando il codice alterna lettura e scrittura delle proprietà del layout all'interno di un ciclo, costringendo il browser a ricalcolare il layout più volte.
Minimizzare il processing time

La strategia è duplice: ottimizzare il codice esistente (rimuovere il codice non necessario e ottimizzare il codice attuale) e distinguere tra il codice che deve essere eseguito prima e dopo l'aggiornamento del layout. Il codice critico per l'aggiornamento del layout deve essere eseguito per primo, e tutto il resto del codice può essere eseguito dopo l'aggiornamento del layout.
- Rimuovere il codice inutilizzato. Sebbene rimuovere il codice inutilizzato possa sembrare ovvio, sulla maggior parte dei siti c'è almeno del codice vecchio inutilizzato che viene semplicemente eseguito senza aggiungere nulla alla pagina né alla UX. La prima cosa da fare è assicurarsi che non ci sia codice in esecuzione che non è necessario. Questo può essere fatto tramite tree shaking, code splitting, ispezione della code coverage in Chrome e utilizzando un buon IDE che segnali il codice inutilizzato. (Suggerimento: dai anche un'occhiata critica alle risorse caricate dal tuo Tag Manager.) Per ulteriori strategie, consulta la nostra guida su 14 metodi per differire il JavaScript.
- Minimizzare il tempo di esecuzione dei callback. Usa un profiler JavaScript per identificare i colli di bottiglia nel tuo codice e puntare a quelle aree per l'ottimizzazione. Considera tecniche come la memoizzazione, il pre-calcolo e il caching per evitare computazioni ridondanti. (Suggerimento: puoi usare il pannello delle prestazioni di Chrome per trovare gli script con tempi di esecuzione lunghi.)
- Dare priorità al codice critico e pianificare il resto del codice. Quando il codice dei callback è stato ottimizzato, suddividi il codice in codice che deve essere eseguito immediatamente e codice che può essere differito. Dai un'occhiata a questo esempio reale:

In questo esempio, i callback degli eventi di Google Tag Manager e Facebook vengono eseguiti prima del codice (React) che precede l'aggiornamento del layout. La soluzione è pianificare l'esecuzione dei callback di GTM e Facebook quando il browser è inattivo. - Evitare il layout thrashing o reflow. Il layout thrashing si verifica quando aggiornamenti e letture degli stili vengono mescolati in un ciclo, causando il ricalcolo del layout da parte del browser numerose volte. Per evitare il layout thrashing, esegui tutte le modifiche agli stili (i "set") prima di richiedere i valori degli stili (i "get"). Questo approccio minimizza la frequenza degli aggiornamenti del layout, portando a una pagina più veloce. Ad esempio, in un ciclo che imposta la larghezza di ogni paragrafo in base alla larghezza di un elemento, leggi la larghezza dell'elemento una volta prima del ciclo e usa quel valore per aggiornare le larghezze dei paragrafi all'interno del ciclo.
Suddividere gli event handler con setTimeout(0)
Quando non è possibile rimuovere o differire il codice da un event handler, la migliore alternativa è suddividere l'handler in porzioni più piccole. Il pattern setTimeout(callback, 0) permette di dividere il lavoro in più task, dando al browser la possibilità di gestire l'aggiornamento del layout tra di essi. Ecco un esempio pratico:
// Before: one long event handler blocks the next paint
button.addEventListener('click', () => {
updateUI(); // Critical: must run before paint
validateForm(); // Important but can wait
sendAnalytics(); // Non-critical
syncLocalStorage(); // Non-critical
});
// After: break into critical and deferred work
button.addEventListener('click', () => {
updateUI(); // Critical: runs immediately before paint
setTimeout(() => {
validateForm();
}, 0);
setTimeout(() => {
sendAnalytics();
syncLocalStorage();
}, 0);
});
Lo svantaggio di setTimeout(0) è che posiziona la continuazione alla fine della coda dei task. Se altri task sono già in coda, il codice differito potrebbe non essere eseguito immediatamente. Per un comportamento più prevedibile, usa invece scheduler.yield() (vedi la sezione seguente). Per i pattern specifici per la gestione dello scrolling JavaScript, consulta la nostra guida dedicata.
Usare requestAnimationFrame per gli aggiornamenti visivi
Quando il tuo event handler deve attivare un aggiornamento visivo, requestAnimationFrame() garantisce che il tuo codice venga eseguito al momento ottimale: subito prima che il browser esegua il prossimo repaint. Questo è particolarmente utile quando devi raggruppare le letture e le scritture del DOM per evitare il layout thrashing.
// Use requestAnimationFrame to batch visual updates
button.addEventListener('click', () => {
// Read layout properties first (outside rAF)
const containerWidth = container.offsetWidth;
requestAnimationFrame(() => {
// Write layout properties inside rAF
items.forEach(item => {
item.style.width = containerWidth + 'px';
});
});
// Schedule non-visual work for idle time
requestIdleCallback(() => {
trackButtonClick();
updateSessionState();
});
});
Questo pattern separa le letture del DOM dalle scritture del DOM, prevenendo il layout sincrono forzato. L'aggiornamento visivo viene eseguito al momento ideale nella pipeline di rendering del browser, e il lavoro non visivo viene eseguito durante il tempo di inattività.
Come dare priorità al codice critico
Il concetto di "dare priorità al codice critico e pianificare il resto del codice" potrebbe essere un po' astratto. Possiamo dare priorità al codice critico utilizzando requestIdleCallback() e cedendo il controllo al main thread.
Usiamo requestIdleCallback per i task meno importanti che non devono essere eseguiti immediatamente. Ecco un esempio prima e dopo della pianificazione di un evento GTM:
/* before: immediately run code */
gtag('event', '<event_name>', {
'event_category': '<event_category>',
});
/* after: run the same code during browser idle */
requestIdleCallback(() => {
gtag('event', '<event_name>', {
'event_category': '<event_category>',
});
}, { timeout: 1000 });
Lo svantaggio di requestIdleCallback è che il codice potrebbe non essere eseguito subito come desiderato. In tal caso, puoi "cedere il controllo al main thread" dopo che il codice più importante è stato eseguito, dando al browser un momento per eseguire l'aggiornamento del layout. Ecco un esempio di come suddividere i task cedendo il controllo al main thread:
async function yieldToMain() {
if ('scheduler' in window && 'yield' in window.scheduler) {
return await window.scheduler.yield();
}
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
}
async function handleClick() {
// Do the most important layout updates here
await yieldToMain();
// Do other tasks that need to run as soon as possible after the layout update
}
Pianificazione granulare con scheduler.postTask()
La funzione scheduler.postTask() fornisce una pianificazione più granulare dei task impostando le priorità, il che aiuta il browser a dare priorità al lavoro in modo che i task a bassa priorità cedano il controllo al main thread. Verifica la tabella di compatibilità dei browser prima di utilizzare questa API in produzione.
La funzione postTask() accetta tre impostazioni di priorità: "background" per i task a priorità più bassa, "user-visible" per i task a priorità media e "user-blocking" per i task critici che richiedono alta priorità.
Assegnando la giusta priorità a ogni porzione di lavoro all'interno del tuo event handler, puoi garantire che il browser gestisca le interazioni dell'utente in modo reattivo completando comunque tutti i task necessari:
// Schedule critical UI work at high priority
scheduler.postTask(() => {
updateCartBadge();
showConfirmation();
}, { priority: 'user-blocking' });
// Schedule data sync at medium priority
scheduler.postTask(() => {
syncCartWithServer();
}, { priority: 'user-visible' });
// Schedule analytics at low priority
scheduler.postTask(() => {
gtag('event', 'add_to_cart', { item: productId });
fbq('track', 'AddToCart');
}, { priority: 'background' });
Implicazioni pratiche
Affrontiamo la domanda più importante: "Cosa significa tutto questo per il mio sito?" Ecco come affrontare l'ottimizzazione del processing time per WordPress e React/Next.js.
WordPress
WordPress offre un controllo limitato quando si tratta di script di terze parti. Molti script vengono aggiunti tramite plugin. La maggior parte delle volte questi script aggiungono event listener alla pagina che non fanno altro che ritardare l'Interaction to Next Paint (INP). Se il tuo sito WordPress ha problemi con l'INP causati da un processing time lungo, segui questi passaggi:
- Controlla le impostazioni del tema. Deseleziona le opzioni non necessarie come "smooth scroll" o "animated menu". Impostazioni come queste tendono a causare problemi di INP.
- Verifica quali script sono responsabili del processing time lungo (suggerimento: usa il pannello delle prestazioni di Chrome). Se questi script sono legati a plugin, considera di trovare un altro plugin che faccia più o meno la stessa cosa con meno JavaScript.
- Spesso ci sono script personalizzati in esecuzione sulla pagina. Controlla questi script e assicurati che cedano spesso il controllo al main thread e avvolgano i callback meno importanti in una funzione
requestIdleCallback. - Rimuovi gli script inutilizzati pagina per pagina (suggerimento: usa
wp_deregister_script). Alcuni plugin tendono a iniettare script in ogni pagina anche quando la funzionalità non è necessaria. - Controlla il tuo Tag Manager e rimuovi i tag inutilizzati o non necessari.
- Usa temi leggeri e puliti. I temi multiuso che "fanno tutto" tendono ad avere più script ed event handler più pesanti.
- Evita i page builder poiché spesso si affidano pesantemente a JavaScript per presentare le pagine all'utente finale.
React / Next.js
Gli hook e le funzionalità di concorrenza di React rendono possibile ridurre significativamente il processing time dell'INP. Ecco le tecniche chiave:
Dare priorità all'interazione dell'utente con le funzionalità di concorrenza di React:
Le funzionalità di concorrenza di React introdotte nelle versioni 16 e 18 forniscono hook e meccanismi per ottimizzare il rendering per una user experience più fluida, specialmente durante l'input.
useTransitionestartTransition: contrassegnano gli aggiornamenti non critici per il rendering successivo. Questo impedisce che aggiornamenti importanti blocchino l'interazione dell'utente. Ad esempio, avvolgi l'aggiornamento dei risultati di ricerca instartTransitionin modo che la digitazione nella casella di ricerca rimanga reattiva.useDeferredValue: suddividi la tua UI in sezioni essenziali e meno critiche. React può interrompere il rendering delle parti meno critiche per un'esperienza più reattiva. Questo è ideale per il rendering di liste filtrate o risultati di ricerca.useOptimistic: mostra uno stato temporaneo e ottimistico mentre le operazioni asincrone (come le richieste di rete) sono in corso. Questo mantiene la UI reattiva anche durante il data fetching.
Suspense per il data fetching (React 18+)
Suspense in React 18 può essere usato per migliorare l'INP permettendo al browser di dare priorità alle interazioni dell'utente e ottimizzare il rendering. Mentre React 16 ha introdotto Suspense per il code splitting, React 18 estende questa funzionalità per includere il data fetching.
- Un componente fallback, come un indicatore di caricamento, viene visualizzato durante il caricamento dei dati.
- Una volta arrivati i dati, React riprende il rendering del componente sospeso.
- Suspense, combinato con il rendering interrompibile in Concurrent React, dà priorità alle interazioni dell'utente. Se un utente interagisce con un componente sospeso, React dà priorità al rendering di quel componente, mantenendo la reattività.
Nel complesso, queste funzionalità lavorano insieme per garantire che React dia priorità alle interazioni dell'utente ed eviti di bloccare la UI durante gli aggiornamenti o il data fetching.
Esplora le altre fasi dell'INP
Il processing time è solo una parte dell'Interaction to Next Paint. Per ottimizzare completamente i tuoi punteggi INP, dovresti anche affrontare le altre due fasi:
- Input Delay: minimizza il tempo di attesa prima che gli event handler inizino l'esecuzione. L'input delay rappresenta circa il 18% del tempo totale dell'INP.
- Presentation Delay: riduci il lavoro di rendering e painting che rappresenta circa il 42% del tempo totale dell'INP.
Per un workflow diagnostico completo, consulta la nostra guida su come trovare e risolvere i problemi di INP e torna alla pagina hub dell'INP per la panoramica completa.
Ask AI why your INP spiked.
CoreDash is the only RUM tool with MCP support. Connect it to your AI agent and query your Core Web Vitals data in natural language. No more clicking through dashboards.
See How It Works
