SEO tecnica

INP – Interaction to Next Paint: come migliorare la reattività del tuo sito

INP è il nuovo Core Web Vital che sostituisce FID e misura la reattività di tutte le interazioni dell'utente. Scopri cos'è, come misurarlo, le cause comuni di degradazione e le strategie pratiche per ottimizzarlo.

A cura di ContatPubblicato il 11 min di lettura
Percorso di un'interazione web dal tap al processamento, layout e paint dello schermo
INP misura il percorso dall'azione al feedback visibile

Dall'interazione al paint

INP segue il percorso completo di un'interazione: input, lavoro del browser, aggiornamento del layout e nuovo paint. Ottimizzare la reattività significa ridurre ogni attesa prima del feedback visibile.

Cos'è INP e perché sostituisce FID

Fino a marzo 2024, Google misurare la reattività con FID (First Input Delay): il tempo tra quando l'utente interagisce (click, tap, pressione tastiera) e quando il browser inizia a processare quel comando.

FID aveva un limite: misurava solo il primo input. Se il tuo sito era lento per tutti gli input eccetto il primo, non lo sapevi. Per questo motivo, INP (Interaction to Next Paint) lo ha sostituito come Core Web Vital.

Definizione: INP misura il tempo totale dall'input dell'utente fino al paint successivo visibile sullo schermo.

INP considera tutte le interazioni durante la sessione (non solo la prima) e premia i siti che rispodono velocemente, coerentemente. Una soglia di INP "buono" è generalmente considerata sotto 200 milliseconds. Se il tuo INP supera i 500ms, è tempo di agire.

Perché Google ha deciso questo cambio? Perché misura meglio la user experience reale. Gli utenti non si fermano dopo il primo click: continuano a interagire con il sito (scroll, filtri, form). Se il sito rallenta dopo il primo input, gli utenti se ne accorgono e si frustrano.

Cosa misura INP: dalla input al paint

INP non è solo il tempo di elaborazione (come FID). È la misura completa di cosa succede quando un utente interagisce.

La timeline di un'interazione

  • Input event: L'utente clicca, digita, scrolls.
  • Processing time: Il browser esegue il JavaScript, aggiorna il DOM, esegue layout e paint.
  • Presentation delay: Il browser attende il frame successivo per visualizzare il risultato.
  • Next Paint: Finalmente l'utente vede il risultato del suo input.

INP misura dall'input all'ultimo paint visibile (next paint). Se il sito impiega 500ms per rispondere a un click, l'utente si accorge di un ritardo di mezzo secondo. Non è accettabile.

La differenza chiave: FID misurava solo il delay prima che il browser iniziasse a processare (input event → inizio processing). INP misura l'intera durata (input event → presentation delay → paint). È una misura più realistica della user experience.

Quale parte conta di più?

Google non divide l'INP in componenti singoli. Misura il totale. Quindi la tua priorità è: quale componente è il bottleneck?

  • Se il main thread è bloccato quando l'utente clicca: il bottleneck è il processing.
  • Se JavaScript finisce veloce ma il paint è lento: il bottleneck è il rendering.
  • Se il sito ha molti event listener: potrebbero aver dei debounce inefficienti.

Cause comuni di INP alto

1. JavaScript pesante e non ottimizzato

Troppo codice JavaScript che gira al click. Se il tuo framework carica 500KB di JS e l'utente clicca, il main thread si blocca per processare quel codice.

Soluzione: Code splitting, lazy loading, tree-shaking per rimuovere JS inutilizzato.

2. Main thread bloccato

Il thread principale del browser è occupato (parsing, execution, layout). Quando l'utente clicca, il browser attende che il main thread sia libero prima di processare l'input. Questo crea un delay enorme.

Soluzione: Ridurre il carico del main thread, usare Web Workers per calcoli pesanti, rinviare le task non critiche.

3. Long tasks (task > 50ms)

Una singola task JavaScript che impiega più di 50ms blocca il main thread. Se ce ne sono più di una al click, il delay si accumula.

Soluzione: Frammentare le long task in piccoli chunk, usare setTimeout() o requestIdleCallback().

4. Event listener inefficienti

Se il tuo sito ha centinaia di event listener e ognuno fa un lavoro pesante, il click attiva più listener e ciascuno compete per il main thread.

Soluzione: Usare event delegation, debouncing, throttling.

5. Rendering lento (paint e layout trashing)

Layout trashing: il tuo codice legge le proprietà del DOM (width, height) che causa un reflow, poi modifica il DOM, che causa un altro reflow. Migliaia di reflow = paint lento.

Soluzione: Batch le operazioni DOM, usa requestAnimationFrame(), evita di mescolare letture e scritture del DOM.

6. Dipendenze dal server lente

Se il click attiva una fetch al server e il server non risponde velocemente, INP ne soffre. Però il server non è il bottleneck principale per INP (è più per la performance percepita).

Soluzione: Ottimizza il backend, usa caching, fetch anticipato.

Come misurare l'INP del tuo sito

Strumento 1: PageSpeed Insights (Google)

Accedi a pagespeed.web.dev, inserisci l'URL del tuo sito, e Google mostra l'INP della pagina di desktop e mobile.

Vantaggi: Ufficiale, gratuito, mostra anche suggerimenti di ottimizzazione, accesso ai dati del Chrome UX Report.

Limitazioni: Misura su un device generico; non riflette i tuoi utenti reali. PageSpeed Insights è un snapshot, non una metrica continuativa.

Strumento 2: Chrome UX Report (CrUX)

Google raccoglie i dati di performance reali dai browser Chrome degli utenti. Puoi accedervi tramite CrUX Dashboard o via BigQuery.

Vantaggi: Dati reali dai tuoi utenti, storico mensile, segmentato per device type e connection type.

Limitazioni: I dati sono pubblici (se il tuo sito ha sufficiente traffico), ci vuole circa un mese per apparire nel CrUX.

Strumento 3: Web Vitals JavaScript Library

Integra la libreria web-vitals nel tuo sito (NPM: web-vitals). Misura INP lato client e invia i dati a Google Analytics o alla tua piattaforma di monitoring.

Codice di esempio:

import {onINP} from 'web-vitals';
onINP(metric => {
  console.log('INP:', metric.value, 'ms');
  // Invia a Google Analytics o al tuo monitoring
});

Vantaggi: Misura reale dal tuo sito, integrazione con GA4 disponibile.

Strumento 4: Chrome DevTools

Apri Chrome DevTools (F12), vai al tab "Performance". Clicca su un elemento, esegui un'azione, e Chrome registra la timeline di processing, rendering, e paint.

Vantaggi: Visione dettagliata di ogni singola operazione, debug preciso.

Limitazioni: È un tool di debug, non per monitoring continuativo.

Strategie pratiche di ottimizzazione

1. Riduci il JavaScript

Meno codice JavaScript = meno processamento al click. Azioni concrete:

  • Code splitting: Carica solo il JS necessario per la pagina corrente. Rinvia il caricamento di script non critici.
  • Tree-shaking: Rimuovi il codice JS non utilizzato durante il build.
  • Minificazione: Riduci la dimensione del JS minificandolo.
  • Upgrade delle dipendenze: Le librerie più vecchie hanno overhead maggiore. Aggiorna a versioni moderne ottimizzate.

2. Usa Web Workers per le task pesanti

Se hai calcoli pesanti (data processing, algoritmi), sposta il lavoro in un Web Worker. Il main thread rimane libero per processare l'input.

3. Frammentazione delle long task

Se hai una task che impiega 200ms, dividila in chunk più piccoli (< 50ms):

// BAD: long task
for (let i = 0; i < 1000000; i++) {
  expensiveCalculation();
}

// GOOD: chunked
function processInChunks(data, chunkSize = 1000) {
  let i = 0;
  function processChunk() {
    for (let j = 0; j < chunkSize && i < data.length; j++, i++) {
      expensiveCalculation(data[i]);
    }
    if (i < data.length) {
      setTimeout(processChunk, 0); // Cede il main thread
    }
  }
  processChunk();
}

4. Event delegation e debouncing

Non aggiungere un listener a cento elementi. Usa event delegation (un listener sul parent) e debounce gli event ricorrenti (scroll, resize, input):

// Debounce esempio
function debounce(func, delay) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), delay);
  };
}

element.addEventListener('input', debounce(() => {
  performSearch();
}, 300));

5. Batch operazioni DOM

Evita di alternare letture e scritture del DOM (layout thrashing):

// BAD: layout thrashing
for (const el of elements) {
  el.style.width = el.offsetWidth + 10 + 'px'; // Legge offset, causa reflow
}

// GOOD: batch
const widths = [];
for (const el of elements) {
  widths.push(el.offsetWidth); // Tutte le letture
}
for (let i = 0; i < elements.length; i++) {
  elements[i].style.width = (widths[i] + 10) + 'px'; // Tutte le scritture
}

6. Prefetch e preload risorse critiche

Se sai che un click caricherà una risorsa (immagine, stylesheet, script), preload anticipatamente:

<link rel="preload" href="/important-script.js" as="script">
<link rel="prefetch" href="/next-page.html">

7. Monitora INP in continuità

Non basta misurare una volta. Integra il monitoraggio INP in GA4 o in un servizio di monitoring. Crea un alert se INP degrada.

Checklist: come migliorare l'INP del tuo sito

Ecco una checklist pratica e ordinata per migliorare l'INP:

  • [ ] Misura l'INP attuale. Usa PageSpeed Insights, CrUX Dashboard, o Web Vitals JS. Baseline stabilita?
  • [ ] Identifica le pagine con INP peggiore. Quali pagine hanno INP > 200ms? Sono homepage, product pages, checkout?
  • [ ] Profilare con Chrome DevTools. Apri Performance tab, simula un'interazione reale (click, scroll), vedi dove il tempo viene speso.
  • [ ] Riduci il carico JavaScript. Audit del JS con Lighthouse. Rimuovi dipendenze non usate. Code splitting su componenti pesanti.
  • [ ] Identifica long task (> 50ms). Chrome DevTools > Performance mostra le long task. Sono dovute a JavaScript, rendering, o parsing?
  • [ ] Frammentazione delle long task. Se è JavaScript, suddividilo in chunk. Usa setTimeout o requestIdleCallback.
  • [ ] Abilita rendering ottimizzato. Profila il rendering: sei sicuro che il layout/paint sia necessario a ogni frame?
  • [ ] Riduci il numero di event listener. Audit quanti listener hai. Usa event delegation.
  • [ ] Debounce gli input ricorrenti. Se hai input/scroll listener che attivano funzioni pesanti, debounce con delay di 200-300ms.
  • [ ] Web Workers per calcoli pesanti. Hai operazioni di data processing, encoding, calcoli complessi? Muovili in un Web Worker.
  • [ ] Monitora INP in produzione. Integra Web Vitals JS in GA4. Crea un dashboard di monitoraggio INP nel tempo.
  • [ ] Definisci un target e un SLA. Esempio: INP < 150ms per il 75° percentile. Comunica il target al team di sviluppo.
  • [ ] Test su dispositivi reali e connessioni lente. Chrome DevTools CPU throttling: ridurre a 4x slowdown. Connessione: throttle a Fast 3G. Ripeti il profilamento.
  • [ ] Revisione settimanale. Ogni settimana, controlla CrUX Dashboard. Se INP degrada, investigare il commit che l'ha causato.

INP sostituisce FID perché misura ciò che conta davvero: la reattività percepita dall'utente durante l'intera sessione. Un sito che risponde velocemente al primo click ma si blocca al secondo è un sito lento. INP te lo dice subito.

Domande su INP e Core Web Vitals

Sì. INP è un Core Web Vital ufficiale e Google lo usa come fattore di ranking. Un sito con INP pessimo rankherà peggio di un competitor con INP buono, a parità di contenuto.
FID misurava solo il delay prima di iniziare a processare il primo input. INP misura l'intera durata dall'input al paint visibile, e considera tutte le interazioni della sessione, non solo la prima.
È nel range 'needs improvement'. La soglia di 'buono' è generalmente sotto 200ms. Se il tuo INP è 250ms, vali ancora meglio di molti siti, ma dovrebbe essere la tua priorità ottimizzarlo.
Usa CrUX Dashboard (se i dati sono pubblici). Inserisci il dominio del competitor. Se il sito ha sufficiente traffico (raro per siti piccoli), Google mostra l'INP pubblicamente. Altrimenti, PageSpeed Insights mette il sito nei risultati di ricerca.
INP misura la reattività del browser, non la velocità del server. Se il tuo backend impiega 5 secondi a rispondere, l'INP è techincamente veloce (il browser processa il click subito). Ma la user experience è comunque pessima. Ottimizza sia INP che il server response time.
Inizia con code splitting e debouncing. Questi hanno zero impatto sul design. Poi profila con Chrome DevTools e identificà le bottleneck precise. Raramente il design stesso è il problema; è il codice che lo supporta.

Ottimizza INP e Core Web Vitals del tuo sito

INP è un fattore di ranking. Ti aiutiamo a misurarlo, identificare i bottleneck e implementare le strategie di ottimizzazione giuste per il tuo progetto.