Performance

Dividere il bundle JavaScript: cosa cambia davvero

Il nostro build produce 48 chunk per 172 kB compressi, e 43 chunk stanno sotto i 15 kB. Come si divide, cosa si guadagna e quando è troppo.

In sintesi

  • Dividere il bundle toglie dal primo paint il codice che serve più tardi.
  • Il nostro build con Vite 5.4.21 produce 48 chunk, 511 kB non compressi e 172 kB gzip.
  • 43 chunk su 48 stanno sotto i 15 kB: il taglio per route funziona.
  • Sotto i 5 kB per chunk il costo della richiesta supera il codice risparmiato.

Dividere il bundle significa caricare all'avvio solo il codice della prima schermata e scaricare il resto quando serve: nel nostro build sono 48 chunk e 172 kB compressi in tutto.

I tre tagli che contano

TaglioCosa separaGuadagnoCosto
RouteUna pagina per filePrimo paint più leggeroUn round trip alla navigazione
VendorDipendenze stabiliCache lunga tra i deployIl chunk vendor resta grande
FeatureCodice pesante usato dopo un clicNiente al caricamentoStato di caricamento da gestire

Il taglio per route è quello che sposta i numeri: l'entry resta piccolo e ogni pagina paga solo il proprio codice. Il taglio vendor serve alla cache, non al primo paint.

Misurare i chunk veri

node -e "const fs=require('fs'),z=require('zlib'),d='client/dist/assets';const f=fs.readdirSync(d).filter(x=>x.endsWith('.js'));let g=0;for(const x of f)g+=z.gzipSync(fs.readFileSync(d+'/'+x)).length;console.log(f.length,'chunk',Math.round(g/1024),'kB gzip')"

Il comando richiede Node e una build già fatta. Risponde a una domanda sola: quanti byte di JavaScript scarica chi apre la prima pagina, e non quanti ne contiene il progetto intero.

Quando è troppo

  • Sotto i 5 kB per chunk il costo della richiesta supera il codice risparmiato.
  • Un chunk per componente moltiplica le richieste e sposta il problema sulla rete.
  • Il prefetch dei chunk di route va reso selettivo: precaricare tutto annulla il taglio.

Il limite da dichiarare

Un chunk in più non è gratis: costa una richiesta, un header e un parse. Con HTTP/2 il costo per richiesta scende, ma parse e compilazione restano sul main thread e su mobile si sentono. Il numero da guardare non è la somma dei chunk ma il grafo che la prima schermata carica davvero.

Dove continuare

Il catalogo EneUI indicizza 111.985 componenti, 1.556 blocchi e il record CPU architecture: un grafico con centinaia di nodi va caricato in un chunk suo, non nell'entry. Per il singolo import che gonfia il bundle leggi un import che aumenta il bundle, per il peso delle librerie UI il peso di una libreria UI, per il confronto misurato librerie React 2026.

Domande frequenti

Code splitting e bundle splitting sono la stessa cosa?

Nella pratica sì: entrambi dividono l'output in più file. Code splitting descrive il taglio nel codice sorgente, bundle splitting l'output del bundler.

Serve un bundler per dividere il bundle?

Non è obbligatorio, ma aiuta: Vite, Rollup e webpack gestiscono i confini dei chunk e i nomi con hash. A mano restano gli import() dinamici.

Sotto quale dimensione il taglio non conviene?

Sotto i 5 kB per chunk: la richiesta costa più del codice che evita, soprattutto su rete mobile.

Il taglio per route rallenta la navigazione?

La prima navigazione paga un round trip. Si compensa con il prefetch del chunk più probabile, non precaricando tutti i chunk.

Come si misura il peso reale?

Con gzip sui file di dist e con la somma dei chunk che la prima pagina carica davvero. Il totale del progetto non è il numero che vede l'utente.