0Pricing
React Academy · Lezione

Riduzione dell'INP: ottimizzazione degli event handler

Esegua il debounce degli handler pesanti, utilizzi scheduler.yield() ed eviti task lunghi che bloccano il thread principale.

Riduzione dell'INP: ottimizzazione degli event handler è una lezione React Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento React Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso React Academy include 4 lezioni in totale.

Che cos'è INP?

Interaction to Next Paint (INP) misura la latenza tra un'interazione dell'utente, come un clic, un tocco o la pressione di un tasto, e il momento in cui il browser visualizza la risposta. Un INP > 200ms dà una sensazione di lentezza.

Perché gli eventi React possono essere lenti

I gestori degli eventi React che eseguono troppo lavoro in modo sincrono bloccano il thread principale. Il browser non può visualizzare la risposta finché l'attività JavaScript non è completata, causando un INP elevato.

Applicare il debounce all'input digitato

Applichi il debounce alle operazioni costose, come le chiamate all'API di ricerca e i calcoli complessi, attivate dalla digitazione. Gli aggiornamenti dello stato React a ogni pressione di tasto vanno bene; è il lavoro costoso che deve essere sottoposto a debounce.

import { useDeferredValue, useState } from 'react';

function SearchPage() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query); // defers re-render of slow parts

  return (
    <>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      <SearchResults query={deferredQuery} /> {/* re-renders with lower priority */}
    </>
  );
}

useTransition per gli aggiornamenti non urgenti

Racchiuda gli aggiornamenti di stato lenti in startTransition per contrassegnarli come non urgenti. React li rimanda, mantenendo reattivo l'input.

const [isPending, startTransition] = useTransition();

function handleFilter(value) {
  setInputValue(value); // urgent — update input immediately
  startTransition(() => {
    setFilteredList(expensiveFilter(value)); // non-urgent — can be interrupted
  });
}

Spostare il lavoro pesante fuori dal thread principale

Usi i Web Worker per le attività che richiedono molta CPU, come l'analisi di dataset di grandi dimensioni e l'elaborazione delle immagini. Il thread principale resta reattivo mentre il worker esegue i calcoli.

const worker = new Worker(new URL('./heavy-worker.js', import.meta.url));

function processData(data) {
  return new Promise(resolve => {
    worker.postMessage(data);
    worker.onmessage = e => resolve(e.data);
  });
}

// In component:
const handleClick = async () => {
  const result = await processData(largeDataset); // doesn't block main thread
  setResult(result);
};

Evitare le attività lunghe

Le attività lunghe (>50ms) bloccano il thread principale e fanno aumentare l'INP. Le suddivida usando setTimeout, scheduler.yield() o requestIdleCallback.

async function processInChunks(items) {
  const CHUNK_SIZE = 100;
  for (let i = 0; i < items.length; i += CHUNK_SIZE) {
    const chunk = items.slice(i, i + CHUNK_SIZE);
    processChunk(chunk);
    await new Promise(r => setTimeout(r, 0)); // yield to browser between chunks
  }
}

scheduler.yield() (API moderna)

scheduler.yield() restituisce il controllo al ciclo di eventi del browser, consentendo di elaborare le interazioni utente in attesa prima di riprendere l'esecuzione del codice.

async function longTask() {
  for (const item of largeList) {
    processItem(item);
    if (/* every N items */) {
      await scheduler.yield(); // let browser handle pending clicks/inputs
    }
  }
}

Evitare layout sincroni nei gestori

La lettura delle proprietà del layout (offsetWidth, getBoundingClientRect()) forza un ricalcolo sincrono del layout. Raggruppi le letture prima delle scritture per evitare il layout thrashing.

// Bad — forces layout recalculation on each iteration:
items.forEach(item => {
  const height = item.offsetHeight; // READ — forces layout
  item.style.height = height * 2 + 'px'; // WRITE — dirties layout
});

// Good — batch reads, then writes:
const heights = items.map(item => item.offsetHeight); // all reads
heights.forEach((h, i) => items[i].style.height = h * 2 + 'px'); // all writes

Actions di React 19 per un INP asincrono

Le Actions di React 19 gestiscono le mutazioni asincrone senza bloccare l'interfaccia: l'aggiornamento dello stato pending avviene indipendentemente, così la pagina resta interattiva.

function LikeButton({ postId }) {
  const [optimistic, setOptimistic] = useOptimistic(false);

  async function handleLike() {
    setOptimistic(true);
    await likePost(postId); // async — doesn't block
  }

  return <button onClick={handleLike}>{optimistic ? 'Liked' : 'Like'}</button>;
}

Problemi della delega degli eventi

React usa la delega degli eventi sintetici, collegando un solo listener alla radice. Eviti di collegare centinaia di listener DOM individuali in useEffect: usi invece gli eventi sintetici di React sugli elementi JSX.

Misurare l'INP in DevTools

Usi il pannello Performance di Chrome DevTools per registrare un'interazione e analizzare le attività lunghe. Cerchi le voci «Interaction» nella timeline ed espanda le voci per trovare le valutazioni degli script che bloccano l'esecuzione.

Verifica rapida

Quale hook React contrassegna un aggiornamento di stato come non urgente, consentendo di interromperlo per gestire le interazioni dell'utente?

Riepilogo

Riduca l'INP applicando il debounce al lavoro costoso, usando startTransition per gli aggiornamenti non urgenti, spostando il lavoro che richiede CPU sui Web Worker e suddividendo le attività lunghe con scheduler.yield(). Raggruppi le letture del DOM prima delle scritture per evitare il layout thrashing.

Domande Frequenti

La lezione «Riduzione dell'INP: ottimizzazione degli event handler» è gratuita?

Sì — il testo completo di «Riduzione dell'INP: ottimizzazione degli event handler» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso React Academy, passa a CoddyKit PRO. Il corso React Academy include 4 lezioni in totale.

Cosa imparerò in «Riduzione dell'INP: ottimizzazione degli event handler»?

Esegua il debounce degli handler pesanti, utilizzi scheduler.yield() ed eviti task lunghi che bloccano il thread principale. Eserciti React Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare React Academy?

Non è richiesta alcuna esperienza precedente. React Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Riduzione dell'INP: ottimizzazione degli event handler»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione React Academy?

Sì. Ogni lezione React Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Misurazione dei Core Web Vitals nelle app React
  2. Analisi del bundle e strategia di code splitting
  3. Ottimizzazione di immagini e font in React
  4. Riduzione dell'INP: ottimizzazione degli event handler
← Torna a React Academy