I budget di prestazioni mantengono le web app veloci fissando limiti chiari su tempi di caricamento, dimensione JS e Core Web Vitals, più audit rapidi e regole "fix-first".

Un budget di prestazioni è un insieme di limiti che si concordano prima di costruire. Può essere un limite di tempo (quanto velocemente la pagina sembra pronta), un limite di dimensione (quanto codice si spedisce) o un semplice tetto (richieste, immagini, script di terze parti). Se si supera il limite, lo si tratta come un requisito rotto, non come un "da sistemare dopo".
La velocità peggiora di solito perché alla spedizione si somma tutto. Ogni nuovo widget aggiunge JavaScript, CSS, font, immagini, chiamate API e lavoro in più per il browser. Anche piccoli cambi si accumulano finché l'app non sembra pesante, specialmente su telefoni di fascia media e reti lente, dove si trova la maggior parte degli utenti reali.
Le opinioni non ti proteggono qui. Una persona dice “va bene sul mio laptop”, un'altra dice “è lento” e il team discute. Un budget chiude il dibattito trasformando le prestazioni in un vincolo di prodotto misurabile e applicabile.
Qui entra il pensiero di Addy Osmani: tratta le prestazioni come vincoli di design e regole di sicurezza. Non “cerchi” di restare sicuro o “speri” che il layout venga bene. Imposti standard, li controlli continuamente e blocchi le modifiche che li infrangono.
I budget risolvono diversi problemi pratici insieme. Rendono espliciti i compromessi (aggiungere una feature significa pagarla da qualche altra parte), catturano le regressioni presto (quando le correzioni costano meno) e danno a tutti la stessa definizione di “abbastanza veloce”. Ridurranno anche il panico dell'ultimo minuto che tende ad arrivare prima di un rilascio.
Ecco il tipo di scenario per cui servono i budget: aggiungi una libreria di grafici ricca per una vista dashboard. Arriva a tutti gli utenti, aumenta il bundle principale e sposta in avanti il primo schermo significativo. Senza un budget, passa perché la feature “funziona”. Con un budget, il team deve scegliere: caricare il grafico in lazy, sostituire la libreria o semplificare la vista.
Questo conta ancora di più quando i team possono generare e iterare app rapidamente, anche con flussi di lavoro guidati dalla chat come Koder.ai. La velocità è ottima, ma rende facile spedire dipendenze extra e abbellimenti UI senza accorgersene. I budget impediscono che un'iterazione rapida diventi prodotti lenti.
Il lavoro sulle prestazioni fallisce quando misuri tutto e non ti prendi la responsabilità di nulla. Scegli una flow di pagina che interessa utenti reali e trattala come l'ancora per i tuoi budget.
Un buon punto di partenza è un percorso primario in cui la velocità influisce sulla conversione o sul lavoro quotidiano, come “home → signup”, “caricamento iniziale del dashboard dopo il login” o “checkout e conferma pagamento”. Scegli qualcosa di rappresentativo e frequente, non un caso limite.
La tua app non gira sul tuo laptop. Un budget che sembra ok su una macchina veloce può sembrare lento su un telefono di fascia media.
Decidi una classe di dispositivo e un profilo di rete per cominciare. Mantieni la cosa semplice e scrivila in una frase che tutti possano ripetere.
Per esempio: un telefono Android di fascia media degli ultimi 2–3 anni, su 4G mentre ci si muove (non la Wi‑Fi dell’ufficio), misurando un cold load e poi una navigazione chiave, nella stessa regione dove si trovano la maggior parte degli utenti.
Non si tratta di scegliere il caso peggiore. Si tratta di scegliere un caso comune su cui si possa davvero ottimizzare.
I numeri contano solo se sono confrontabili. Se una run è “Chrome con estensioni su MacBook” e la successiva è “mobile throttled”, la tua serie storica è rumore.
Scegli un ambiente di riferimento e mantienilo per i controlli del budget: stessa versione del browser, stesse impostazioni di throttling, stesso percorso di test e stesso stato della cache (cold o warm). Se usi dispositivi reali, usa lo stesso modello.
Ora definisci cosa significa “abbastanza veloce” in termini di comportamento, non di demo perfette. Per esempio: “gli utenti possono iniziare a leggere il contenuto rapidamente” o “il dashboard risulta reattivo dopo il login”. Traduci questo in una o due metriche per quel percorso e imposta budget attorno a esse.
I budget funzionano meglio quando coprono sia ciò che gli utenti percepiscono sia ciò che i team possono controllare. Un buon set mescola metriche di esperienza (la parte “è sembrato veloce?”) con limiti di risorse e CPU (la parte “perché è rallentato?”).
Questi tracciano come la pagina si comporta per le persone reali. I più utili si mappano direttamente ai Core Web Vitals:
I budget di timing sono la tua stella polare perché corrispondono alla frustrazione dell'utente. Ma non dicono sempre cosa correggere, quindi servono anche gli altri tipi di budget.
Questi sono più facili da far rispettare nelle build e nelle review perché sono concreti.
I budget di peso limitano cose come total JavaScript, total CSS, peso delle immagini e dei font. I budget di richieste limitano il numero totale di richieste e gli script di terze parti, riducendo l'overhead di rete e il lavoro “a sorpresa” di tag, widget e tracker. I budget di runtime limitano i long task, il tempo sul main thread e il tempo di hydration (specialmente per React), che spesso spiegano perché una pagina “sembra” lenta sui telefoni di fascia media.
Un esempio pratico in React: la dimensione del bundle può sembrare accettabile, ma un nuovo carosello aggiunge rendering pesante client-side. La pagina si carica, eppure toccare i filtri è scattoso perché l'hydration blocca il main thread. Un budget di runtime come “nessun long task oltre X ms durante l'avvio” o “hydration completata entro Y secondi su un dispositivo di fascia media” può intercettare questo anche quando i budget di peso non lo fanno.
L'approccio più forte tratta tutto come un sistema unico: i budget di esperienza definiscono il successo, e i budget di dimensione, richieste e runtime mantengono onesti i rilasci e rendono facile rispondere a “cos'è cambiato?”.
Se imposti troppi limiti, le persone smettono di fare attenzione. Scegli 3–5 budget che rispecchino ciò che gli utenti avvertono di più e che puoi misurare a ogni pull request o rilascio.
Un set di partenza pratico (affina i numeri dopo):
Due soglie mantengono la cosa sensata. “Warn” indica che stai deragliando. “Fail” blocca un rilascio o richiede approvazione esplicita. Questo rende il limite reale senza creare allarmi continui.
Scrivi il budget in un posto condiviso così nessuno lo discute durante un rilascio impegnativo. Sii breve e specifico: quali pagine o flow sono coperti, dove si eseguono le misurazioni (audit locale, CI, build staged), quale dispositivo e profilo di rete usi e esattamente come sono definite le metriche (field vs lab, gzip vs raw, livello route vs intera app).
Inizia con un baseline che puoi ripetere. Scegli una o due pagine chiave e testale sullo stesso profilo dispositivo e rete ogni volta. Esegui il test almeno tre volte e registra la mediana così una run anomala non ti cambia la direzione.
Usa un foglio di base semplice che includa sia una metrica utente sia una metrica di build. Per esempio: LCP e INP per la pagina, più dimensione JS totale e byte immagine totali per la build. Questo fa sentire i budget reali perché vedi cosa è stato spedito, non solo cosa ha stimato un test di laboratorio.
Imposta i budget leggermente migliori rispetto a oggi, non numeri da fantascienza. Una regola solida è il 5–10% di miglioramento dalla mediana attuale su ogni metrica che ti interessa. Se il tuo LCP è 3.2s nel setup di riferimento, non saltare direttamente a 2.0s. Parti da 3.0s e poi stringi quando dimostri di poterlo mantenere.
Aggiungi un controllo rapido a ogni rilascio prima che gli utenti lo vedano. Mantienilo abbastanza veloce da non essere saltato. Una versione semplice è: esegui un audit su una singola pagina concordata, fai fallire la build se JS o immagini superano il budget, salva i risultati per commit così puoi vedere quando è cambiato e testa sempre lo stesso pattern di URL (niente dati casuali).
Revisiona le violazioni settimanalmente, non solo quando qualcuno si lamenta. Tratta una violazione come un bug: identifica la modifica che l'ha causata, decidi cosa sistemare subito e cosa pianificare. Stringi gradualmente, solo dopo aver mantenuto il limite per qualche rilascio.
Quando il perimetro prodotto cambia, aggiorna i budget deliberatamente. Se aggiungi un nuovo strumento di analytics o una feature pesante, annota cosa è cresciuto (dimensione, richieste, runtime), cosa farai per rimediare dopo e quando il budget dovrebbe tornare ai livelli concordati.
Un budget aiuta solo se puoi verificarlo rapidamente. L'obiettivo di un audit di 10 minuti non è dimostrare un numero perfetto. È individuare cosa è cambiato dall'ultimo buon build e decidere cosa correggere per primo.
Inizia con una pagina che rappresenta l'uso reale. Poi esegui sempre gli stessi controlli rapidi:
Due viste di solito danno risposte in pochi minuti: la waterfall di rete e la timeline del main-thread.
Nella waterfall, cerca una richiesta che domina il percorso critico: uno script gigante, un font bloccante o un'immagine che parte tardi. Se la risorsa LCP non viene richiesta presto, la pagina non può rispettare un budget LCP per quanto veloce sia il server.
Nella timeline, cerca i long task (>=50 ms). Un cluster di long task durante l'avvio spesso significa troppo JavaScript al primo caricamento. Un chunk enorme è di solito un problema di routing o un bundle condiviso che è cresciuto col tempo.
Gli audit rapidi falliscono quando ogni run è diversa. Cattura alcune basi così i cambi sono chiari: URL della pagina e build/versione, modello dispositivo e profilo rete, descrizione dell'elemento LCP, i numeri chiave che tracci (per esempio LCP, totale byte JS, numero di richieste) e una breve nota sul colpevole principale.
I test desktop vanno bene per feedback rapidi e controlli di PR. Usa un dispositivo reale quando sei vicino al budget, quando la pagina sembra scattosa o quando i tuoi utenti sono per lo più mobile. Le CPU mobili rendono i long task evidenti, ed è lì che molte release “va bene sul mio laptop” falliscono.
Quando un budget fallisce, la peggior cosa è “ottimizzare tutto”. Usa un ordine di triage ripetibile così ogni correzione ha un payoff chiaro.
Inizia da ciò che gli utenti notano di più, poi scendi verso le ottimizzazioni più fini:
Un team pubblica una nuova dashboard e improvvisamente non rispetta più il budget LCP. Invece di toccare prima gli header di cache, trovano che l'elemento LCP è un'immagine grafica a tutta larghezza. La ridimensionano, la servono in un formato più leggero e caricano solo ciò che conta all'inizio. Poi notano che una grande libreria di grafici viene caricata su ogni route. La caricano solo nella pagina analytics e posticipano un widget di supporto di terze parti fino alla prima interazione. In un giorno, la dashboard torna entro i limiti e nel rilascio successivo c'è chiarezza su “cosa è cambiato”.
Il modo più diffuso di fallire è trattare i budget come un documento una tantum. I budget funzionano solo se sono facili da controllare, difficili da ignorare e legati al modo in cui fai shipping.
La maggior parte dei team resta impantanata in alcuni tranelli:
Un pattern comune è una feature “piccola” che introduce una nuova libreria. Il bundle cresce, LCP rallenta di un secondo sulle reti più lente e nessuno se ne accorge fino all'arrivo dei ticket di supporto. I budget servono a rendere visibile quel cambiamento al momento della review.
Parti semplice e mantieni i controlli coerenti. Scegli 2–4 budget che mappino l'esperienza utente e stringili gradualmente. Blocca il tuo setup di test e scrivilo. Traccia almeno un segnale reale utente se puoi, e usa i test di laboratorio per spiegare il “perché”, non per vincere discussioni. Quando una dipendenza aggiunge peso significativo, richiedi una breve nota: quanto costa, cosa sostituisce e perché vale la pena. Soprattutto, metti il controllo del budget nel percorso di rilascio normale.
Se i budget sembrano solo attrito costante, di solito sono irrealistici per oggi o non sono legati a decisioni reali. Risolvi prima queste due cose.
Un piccolo team ha spedito una dashboard analytics in React in una settimana. All'inizio sembrava veloce, ma ogni rilascio del venerdì l'ha appesantita un po'. Dopo un mese gli utenti hanno iniziato a dire che il primo schermo “si blocca” e i filtri sono lenti.
Hanno smesso di discutere su “abbastanza veloce” e hanno scritto i budget legati a ciò che gli utenti notavano:
La prima violazione è emersa in due punti. Il bundle JS iniziale era cresciuto con l'aggiunta di chart, librerie di date e un UI kit. Allo stesso tempo, l'immagine header della dashboard era stata sostituita con un file più grande “giusto per ora”, portando il LCP oltre il limite. L'INP peggiorava perché ogni cambio filtro innescava rerender pesanti ed elaborazioni costose sul main thread.
Hanno risolto nell'ordine che dava vittorie rapide e preveniva regressioni:
Riportare LCP sotto la soglia ridimensionando e comprimendo le immagini, impostando dimensioni esplicite e evitando font bloccanti.
Ridurre il JS iniziale rimuovendo librerie non usate, dividendo le route non critiche e caricando i grafici in lazy.
Migliorare INP memoizzando componenti costose, debouncing nei filtri di digitazione e spostando lavoro pesante fuori dal percorso critico.
Aggiungere un controllo budget a ogni rilascio così se una metrica si rompe il rilascio aspetta.
Dopo due release, LCP è sceso da 3.4s a 2.3s e INP è migliorato da circa 350ms a sotto 180ms sullo stesso dispositivo di test.
Un budget aiuta solo se le persone lo seguono sempre allo stesso modo. Mantienilo piccolo, scrivilo e rendilo parte dello shipping.
Scegli poche metriche che si adattino alla tua app, imposta soglie “warn vs fail” e documenta esattamente come testi (dispositivo, browser, rete, pagina/flow). Salva un report baseline dall'ultima release buona e etichettalo chiaramente. Decidi cosa conta come eccezione valida e cosa no.
Prima di ogni rilascio, esegui lo stesso audit e confrontalo con il baseline. Se qualcosa regredisce, registralo dove tracci i bug e trattalo come uno step di checkout rotto, non come "dopo". Se spedisci con un'eccezione, registra un owner e una data di scadenza (spesso 1–2 sprint). Se l'eccezione viene rinnovata continuamente, i budget richiedono una discussione seria.
Sposta i budget prima nella pianificazione e nelle stime: “Questa schermata aggiunge una libreria di grafici, quindi dobbiamo rimuovere qualcos'altro o caricarla in lazy.” Se costruisci con Koder.ai (Koder.ai), puoi anche scrivere questi vincoli in Planning Mode, poi iterare in fette più piccole e usare snapshot e rollback quando una modifica supera un tetto. L'importante non è lo strumento, ma l'abitudine: ogni nuova feature deve pagare il suo peso, o non viene spedita.
Un budget di prestazioni è un insieme di limiti stringenti (tempo, dimensione, richieste, lavoro CPU) che il tuo team concorda prima di sviluppare.
Se una modifica supera il limite, trattala come un requisito rotto: correggila, riduci lo scope o approva esplicitamente un'eccezione con un responsabile e una data di scadenza.
Perché le prestazioni peggiorano gradualmente. Ogni feature aggiunge JavaScript, CSS, immagini, font, chiamate API e tag di terze parti.
I budget fermano questa lenta erosione obbligando a un compromesso: se aggiungi peso o lavoro, devi rimediare (lazy-load, dividere una route, semplificare l'interfaccia, rimuovere una dipendenza).
Scegli un singolo percorso utente reale e un setup di test coerente.
Un buon punto di partenza è qualcosa di frequente e critico per il business, come:
Evita i casi limite all'inizio; vuoi un flusso che puoi misurare a ogni rilascio.
Inizia con un target che somigli ai tuoi utenti tipici, per esempio:
Scrivilo e mantienilo stabile. Se cambi dispositivo, rete, stato della cache o il percorso testato, la tua serie storica diventa rumore.
Usa un piccolo set che copra sia ciò che gli utenti percepiscono sia ciò che il team può controllare:
Un set pratico iniziale è:
Usa due soglie:
Questo evita continui allarmi pur rendendo i limiti concreti quando li superi.
Segui questo ordine:
Non sempre. La dimensione del bundle può andare bene mentre la pagina sembra lenta perché il main thread è occupato.
Cause comuni in React:
Aggiungi un budget di runtime (per esempio limiti sui long task in startup o un tempo massimo di hydration) per intercettare questi problemi.
La generazione rapida può aggiungere dipendenze, abbellimenti UI e script di terze parti che arrivano a tutti.
La soluzione è integrare i budget nel flusso:
Questo evita che l'iterazione veloce si trasformi in un prodotto lento.
Le metriche di timing mostrano il dolore; i limiti di dimensione e runtime aiutano a trovare rapidamente la causa.
Scegli 3–5 budget iniziali. Affina i numeri dopo aver preso un baseline.
Tratta la violazione come un bug: identifica il commit, correggi o riduci lo scope e previeni ricorrenze.