INP Presentation Delay: dimensioni del DOM, lavoro di layout e ottimizzazione del rendering

Scopri come identificare e migliorare i problemi di INP causati dal presentation delay

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-04
[include]breadcrumbs.html[\/include]

Problemi di Interaction to Next Paint (INP) causati dal presentation delay

Questa pagina fa parte della nostra serie sull'[url=\/core-web-vitals\/interaction-to-next-paint]Interaction to Next Paint (INP)[\/url]. L'INP misura il tempo totale che intercorre tra un'interazione dell'utente e il successivo aggiornamento visivo. Il presentation delay è la terza e ultima fase dell'INP, dopo l'[url=\/core-web-vitals\/interaction-to-next-paint\/input-delay]input delay[\/url] e il [url=\/core-web-vitals\/interaction-to-next-paint\/processing-time]processing time[\/url]. Se non conosci l'INP, leggi prima la nostra guida su come [url=\/core-web-vitals\/interaction-to-next-paint\/fix-and-identify]identificare e risolvere i problemi di INP[\/url].

In breve: l'Interaction to Next Paint (INP) misura quanto tempo impiega un utente a vedere un cambiamento visivo su una pagina dopo aver interagito con essa. L'INP può essere scomposto in 3 componenti: "input delay", "processing time" e "presentation delay".

Il presentation delay è il principale contributore all'INP totale, rappresentando in media circa il 42% del tempo totale dell'INP. Ottimizzare la pipeline di rendering e semplificare la struttura HTML è la leva principale per migliorare l'INP.

Presentation Delay: ti è mai capitato di cliccare su un pulsante e chiederti perché ci sia voluto un istante di troppo per vedere il risultato? Questa è l'Interaction to Next Paint (INP) in azione. Il presentation delay è l'ultima fase del processo di interazione, che interviene dopo che il clic è stato elaborato ma prima di vedere qualsiasi cambiamento visivo.

[include]toc.html[\/include]

Capire il presentation delay

La presentazione è la fase finale di un'interazione. Il presentation delay rappresenta il tempo impiegato dal browser per renderizzare gli aggiornamenti visivi che seguono l'interazione. Il presentation delay inizia quando gli event handler dell'interazione hanno terminato l'esecuzione e termina quando viene dipinto il frame successivo (contenente le modifiche visive). Il presentation delay può essere influenzato da vari fattori, tra cui la complessità del layout, le dimensioni del DOM e la quantità di lavoro di rendering richiesto.

L'Interaction to Next Paint (INP) può essere scomposto in 3 sottocomponenti: "Input Delay", "Processing Time" e "Presentation Delay".

Presentation delay e l'INP

Il presentation delay è l'ultima fase dell'INP. In media, il presentation delay costituisce circa il 42% del tempo totale dell'INP, rendendolo il principale responsabile delle interazioni lente.

In [url=https:\/\/coredash.app]CoreDash[\/url] raccogliamo milioni di punti dati relativi ai Core Web Vitals ogni ora. In base a questi dati, il presentation delay rappresenta il 42% dell'Interaction to Next Paint. Si tratta di una percentuale superiore al [url=\/core-web-vitals\/interaction-to-next-paint\/processing-time]processing time[\/url] (40%) e significativamente superiore all'[url=\/core-web-vitals\/interaction-to-next-paint\/input-delay]input delay[\/url] (18%). Nonostante sia il principale responsabile, il presentation delay è spesso la fase più difficile da ottimizzare perché coinvolge la pipeline di rendering del browser piuttosto che il codice dell'applicazione.

Esempio di presentation delay: immagina di navigare con il tuo telefono su un sito di e-commerce alla ricerca di un nuovo paio di scarpe. Tocchi l'immagine di un prodotto per vedere maggiori dettagli. Tuttavia, il tuo telefono è un po' datato e fa fatica a stare al passo. Tocchi l'immagine (Interazione). Il telefono impiega del tempo per elaborare la richiesta e aggiornare il display (Processing Time). Il sito web deve renderizzare la nuova pagina con l'immagine più grande e i dettagli. Infine, trascorre un tempo percepibile prima che i nuovi dettagli del prodotto e l'immagine appaiano sullo schermo (Presentation Delay). Questo ritardo nell'INP può essere frustrante per gli utenti ed è per questo che è importante risolverlo.

Cosa causa un presentation delay elevato?

Il presentation delay comprende tutto il lavoro che il browser svolge dopo che gli event handler sono terminati e prima che i pixel appaiano sullo schermo. Questo include il ricalcolo degli stili, il calcolo del layout, il painting e il compositing. Diversi fattori contribuiscono a un presentation delay elevato:

Dimensioni eccessive del DOM

Un DOM di grandi dimensioni o con un annidamento profondo è una delle cause più comuni di un presentation delay elevato. Ogni volta che il browser deve aggiornare lo stato visivo della pagina dopo un'interazione, deve ricalcolare gli stili, calcolare il layout e ridisegnare gli elementi interessati. Il costo di ciascuno di questi passaggi scala con il numero di nodi DOM interessati.

Google consiglia di mantenere il DOM al di sotto di 1.400 elementi, con una profondità massima di 32 livelli e non più di 60 elementi figli per nodo genitore (vedi l'[url=https:\/\/developer.chrome.com\/docs\/lighthouse\/performance\/dom-size]audit sulle dimensioni del DOM di Lighthouse[\/url]). Quando il DOM supera queste soglie, il browser dedica molto più tempo al ricalcolo degli stili e al calcolo del layout dopo ogni interazione.

Considera questo scenario: un utente clicca su un pulsante che attiva una classe CSS su un elemento contenitore. Se quel contenitore ha 5.000 nodi discendenti, il browser deve ricalcolare gli stili potenzialmente per tutti, anche se solo pochi elementi cambiano effettivamente a livello visivo. Questo ricalcolo degli stili avviene in modo sincrono prima del paint successivo, aumentando direttamente il presentation delay.

Per tecniche specifiche su come ridurre il DOM, leggi la nostra guida su come [url=\/pagespeed\/fix-avoid-excessive-dom-size-lighthouse]risolvere le dimensioni eccessive del DOM[\/url].

Lavoro di layout eccessivo

Il layout (chiamato anche "reflow") è il processo in cui il browser calcola la posizione e le dimensioni di ogni elemento visibile sulla pagina. Dopo un'interazione che modifica il DOM o cambia le proprietà CSS che influenzano la geometria (width, height, margin, padding, top, left), il browser deve eseguire il layout prima di poter dipingere il frame aggiornato.

Due pattern sono particolarmente dannosi per il presentation delay:

Il Forced synchronous layout si verifica quando JavaScript legge una proprietà di layout (come offsetHeight o getBoundingClientRect()) dopo aver effettuato una modifica al DOM che invalida il layout. Il browser è costretto a eseguire il layout in modo sincrono, all'interno dell'event handler, per restituire un valore accurato. Questo lavoro di layout diventa quindi parte del processing time, ma ogni layout successivo innescato da ulteriori modifiche al DOM diventa parte del presentation delay.

Il Layout thrashing è il pattern ripetuto di scrittura sul DOM e successiva lettura delle proprietà di layout in un ciclo. Ogni lettura costringe il browser a ricalcolare il layout, e ogni scrittura invalida nuovamente il layout. Questo può causare decine o addirittura centinaia di calcoli di layout non necessari per interazione. Ecco un esempio di layout thrashing e come risolverlo:

\/\/ MALE: Layout thrashing all'interno di un ciclo
function resizeItems() {
  const items = document.querySelectorAll('.item');
  items.forEach(item => {
    \/\/ Lettura (forza il layout)
    const parentWidth = item.parentElement.offsetWidth;
    \/\/ Scrittura (invalida il layout)
    item.style.width = parentWidth + 'px';
  });
}

\/\/ BENE: Letture in batch, poi scritture in batch
function resizeItems() {
  const items = document.querySelectorAll('.item');
  \/\/ Leggi prima tutti i valori
  const widths = Array.from(items).map(
    item => item.parentElement.offsetWidth
  );
  \/\/ Quindi scrivi tutti i valori
  items.forEach((item, i) => {
    item.style.width = widths[i] + 'px';
  });
}

                

Rendering lato client nelle Single Page Applications

Il rendering lato client dell'HTML può influenzare significativamente il presentation delay, in particolare nelle Single Page Applications (SPA). Quando un'interazione dell'utente innesca un cambio di rotta o un aggiornamento massiccio dell'interfaccia utente, il framework SPA deve:

  1. Eseguire l'algoritmo di diffing del DOM virtuale per determinare cosa è cambiato
  2. Applicare le mutazioni DOM risultanti al DOM reale
  3. Innescare il ricalcolo degli stili e il layout per tutti gli elementi interessati
  4. Dipingere il frame aggiornato

    Nelle applicazioni React, il processo di riconciliazione del DOM virtuale fa parte del processing time, ma le mutazioni DOM risultanti e il loro costo di rendering rientrano nel presentation delay. Più nodi DOM produce l'albero dei componenti, più costosi saranno la riconciliazione e il successivo lavoro di rendering.

    Per mitigare questo problema nelle applicazioni React e Next.js:

    • Usa React.memo() per evitare re-render non necessari dei componenti figli che ricevono le stesse prop.
    • Usa useDeferredValue() per i valori che innescano re-render costosi, consentendo a React di dare priorità agli aggiornamenti più urgenti.
    • Mantieni gli alberi dei componenti poco profondi. Gerarchie di componenti profondamente annidate producono un DOM profondamente annidato, che aumenta il costo sia della riconciliazione che del rendering del browser.
    • Usa librerie di virtualizzazione (come react-window o @tanstack\/react-virtual) per liste lunghe, in modo che il DOM contenga solo gli elementi visibili.

      Ridurre il presentation delay

      Minimizzare le dimensioni del DOM

      Il vantaggio principale per il presentation delay è mantenere il DOM piccolo:

      • Rimuovi gli elementi HTML non utilizzati, specialmente i div wrapper profondamente annidati.
      • Usa la virtualizzazione delle liste per le liste lunghe (renderizza solo gli elementi visibili più un piccolo buffer).
      • Appiattisci le strutture profondamente annidate dove possibile.
      • Usa CSS Grid e Flexbox invece dei div annidati per il layout.
        \/\/ Virtualizza le liste lunghe per ridurre le dimensioni del DOM
        \/\/ Prima: 10.000 elementi nel DOM
        
        <ul>
          {allItems.map(item => 
             <li key="{item.id}">{item.name}<\/li>)
           }
        <\/ul>
        
        \/\/ Dopo: solo gli elementi visibili nel DOM (usando react-window)
        import { FixedSizeList } from 'react-window';
        

        Usare content-visibility per il rendering differito dei contenuti fuori dallo schermo

        La proprietà CSS content-visibility indica al browser di saltare il rendering dei contenuti fuori dallo schermo finché l'utente non scorre vicino ad essi. Ciò riduce la quantità di lavoro di rendering durante le interazioni limitando l'ambito del ricalcolo degli stili e del layout alla parte visibile della pagina.

        \/* Applica content-visibility alle sezioni below-the-fold *\/
        .below-fold-section {
          content-visibility: auto;
          contain-intrinsic-size: auto 500px;
        }
        
        \/* Applica ai singoli elementi nelle liste lunghe *\/
        .list-item {
          content-visibility: auto;
          contain-intrinsic-size: auto 80px;
        }
                        

        La proprietà contain-intrinsic-size fornisce un'altezza stimata in modo che il browser possa calcolare correttamente le dimensioni della barra di scorrimento senza renderizzare il contenuto. Ciò evita salti di layout quando l'utente scorre e il contenuto diventa visibile.

        Per ulteriori strategie di ottimizzazione CSS che riducono i costi di rendering, consulta la nostra guida su come [url=\/pagespeed\/fix-remove-unused-css-lighthouse]rimuovere i CSS non utilizzati[\/url].

        Minimizzare il lavoro di layout innescato dalle interazioni

        Quando progetti le interazioni, preferisci le proprietà CSS che non innescano il layout. Proprietà come transform e opacity possono essere gestite dal compositor della GPU senza innescare layout o paint. Invece di animare top, left, width o height, usa transform: translate() e transform: scale(). Per l'elenco completo delle proprietà CSS che innescano il layout, consulta la [url=https:\/\/web.dev\/articles\/rendering-performance]guida alle prestazioni di rendering di web.dev[\/url].

        Usa la proprietà CSS will-change per suggerire al browser che un elemento verrà animato. Ciò consente al browser di creare un livello di compositor separato per l'elemento, isolando il suo rendering dal resto della pagina:

        \/* Promuovi gli elementi al proprio livello di compositor *\/
        .animated-element {
          will-change: transform, opacity;
        }
        
        \/* Attiva la visibilità con l'opacità invece che con il display *\/
        .modal {
          opacity: 0;
          pointer-events: none;
          transform: translateY(10px);
          transition: opacity 0.2s, transform 0.2s;
        }
        
        .modal.active {
          opacity: 1;
          pointer-events: auto;
          transform: translateY(0);
        }
        
                        

        Identificare i ritardi di presentation delay elevati

        Per identificare i ritardi di presentation delay elevati puoi utilizzare il profiler delle prestazioni di Chrome. Apri DevTools (Ctrl+Shift+I), vai alla scheda Performance, premi registra e interagisci con la pagina.

        Puoi quindi analizzare la timeline di un'interazione e visualizzare le diverse fasi, incluso il presentation delay. Esaminando gli aggiornamenti del rendering che si verificano dopo che gli event handler sono terminati, puoi individuare eventuali colli di bottiglia che contribuiscono a un lungo presentation delay. Cerca le voci "Recalculate Style", "Layout" e "Paint" di grandi dimensioni nella timeline. Queste rappresentano il lavoro svolto dal browser durante la fase di presentation delay.

        Identificare il presentation delay con i dati RUM
        Il Real User Monitoring (RUM) fornisce aggiornamenti in tempo reale su importanti metriche relative ai Core Web Vitals come l'Interaction to Next Paint e le sue sottocomponenti, incluso il presentation delay. Uno strumento RUM come [url=https:\/\/coredash.app]CoreDash[\/url] scompone ogni interazione INP nelle sue tre fasi, permettendoti di vedere se il presentation delay è il collo di bottiglia per le tue pagine specifiche e i segmenti di utenti.

        Misurare il presentation delay con i Long Animation Frames (LoAF)

        L'API Long Animation Frames (LoAF) mostra esattamente cosa causa i ritardi di rendering durante le interazioni dell'utente. L'API fornisce dati temporali per separare il processing time dal presentation delay e individuare quali script rallentano il rendering.

        Le proprietà chiave di LoAF per capire il presentation delay sono:

        • renderStart: quando il browser ha iniziato la fase di rendering (ricalcolo dello stile, layout, paint)
        • styleAndLayoutStart: quando è iniziato il calcolo dello stile e del layout
        • duration: durata totale del long animation frame
        • blockingDuration: quanto del frame è stato bloccato dagli script

          LoAF è attualmente disponibile solo su Chromium (Chrome 123+). Per altri browser, usa le tracce del pannello Performance di Chrome DevTools per analizzare il lavoro di rendering.

          La differenza tra la fine dell'esecuzione dello script e la fine del frame rappresenta il puro costo di rendering, ovvero il presentation delay. Ecco come osservare e loggare questi dati:

          \/\/ Misura il presentation delay utilizzando l'API LoAF
          const observer = new PerformanceObserver((list) => {
            for (const entry of list.getEntries()) {
              if (entry.duration > 50) {
                const scriptEnd = Math.max(
                  ...entry.scripts.map(s => s.startTime + s.duration)
                );
                const presentationDelay = (
                  entry.startTime + entry.duration
                ) - Math.max(scriptEnd, entry.renderStart);
          
                console.log('Presentation delay breakdown:', {
                  totalDuration: entry.duration,
                  renderStart: entry.renderStart,
                  styleAndLayoutStart: entry.styleAndLayoutStart,
                  estimatedPresentationDelay: presentationDelay,
                  scriptCount: entry.scripts.length
                });
              }
            }
          });
          
          observer.observe({
            type: 'long-animation-frame',
            buffered: true
          });
                          

          Gli strumenti RUM come CoreDash integrano i dati LoAF e mostrano quali script e modifiche al DOM causano ritardi nel rendering, con l'attribuzione completa dello script.

          Esplora le altre fasi dell'INP

          Per tenere sotto controllo l'INP, affronta anche le altre due fasi: