Performance

Code splitting per route: caricare solo il codice della pagina

Il code splitting per route divide il bundle in un file per pagina: la prima visita scarica solo ciò che le serve. Come si configura e cosa misurare.

In sintesi

  • Il code splitting per route sposta fuori dal primo caricamento il codice che la pagina non usa.
  • Il build del 1 novembre 2026 ha prodotto 48 file JavaScript per 523.037 byte, 176.211 in gzip.
  • L'entry resta a 141.302 byte: il guadagno arriva dai chunk che non scarichi.

Il code splitting per route divide il bundle in un file per pagina, così la prima visita scarica solo il codice che le serve. Il build di questo sito produce 48 file JavaScript, ma la home ne richiede uno solo.

Un import dinamico per route

import { lazy, Suspense } from "react";

const Components = lazy(() => import("./pages/Components"));
const Blocks = lazy(() => import("./pages/Blocks"));

export function Routes({ tab }) {
  return (
    Loading}>
      {tab === "components" ?  : }
    
  );
}

Ogni import() crea un punto di separazione: Vite emette un file per il modulo raggiunto solo da quel punto. Il codice condiviso da più route finisce nel chunk comune, non duplicato in ognuna.

Quattro modi di spezzare

TecnicaCosa separaQuando serve
import() per routeuna pagina per fileSPA con più viste
manualChunksdipendenze condivise in un filelibrerie pesanti usate ovunque
prefetch su inattivitàil chunk della route successivanavigazione prevedibile
import condizionalecodice dietro un flageditor e pannelli admin

Dove si vede il guadagno

L'entry non si restringe: resta a 141.302 byte perché contiene React e il router. Il guadagno è nei chunk che la home non richiede: Blocks pesa 22.130 byte e arriva solo quando apri quella pagina. Su una visita alla home il risparmio è la somma dei chunk che non scarichi.

Il comando

npx vite build --mode production

L'output elenca ogni file con la dimensione in kB e scrive client/dist. Aggiungi --sourcemap quando devi capire quale modulo finisce in quale chunk.

La limitazione

Le dimensioni del build non sono byte trasferiti: 48 file esistono su disco, ma una visita ne scarica pochi. Spezzare troppo crea round trip in più sulle route profonde, e un chunk duplicato pesa più dell'entry che volevi evitare. Leggi le richieste nel pannello Network, non la cartella dist.

Dove continuare

Il catalogo EneUI indicizza 111.985 componenti e 1.556 blocchi con preview. Il record sidebar è un componente fatto di più file: importato staticamente finisce nell'entry. Per il peso di un singolo import leggi un import che aumenta il bundle, per la compressione Brotli contro gzip, per il confronto tra librerie il peso delle librerie UI, per la parte di CSS che blocca il paint il CSS critico.

Domande frequenti

Che differenza c'è tra code splitting e tree shaking?

Il tree shaking toglie dal bundle il codice mai importato, il code splitting divide ciò che resta in file caricati su richiesta. Servono entrambi: il primo riduce il totale, il secondo riduce ciò che parte subito.

Ogni route deve avere il suo file?

No. Conviene separare le route pesanti e quelle visitate di rado; una route da 3 KB non guadagna nulla da un file in più. Raggruppa le viste piccole e lascia un chunk per le grandi.

Il chunk separato arriva prima o dopo il primo paint?

Dopo, perché il browser lo chiede quando il componente viene montato. Con React.lazy la richiesta parte al primo render della route, quindi il fallback di Suspense è ciò che l'utente vede nel frattempo.

Come evito che una libreria finisca in più chunk?

Dichiara un gruppo manuale in build.rollupOptions.output.manualChunks per le dipendenze condivise. Rollup estrae il modulo in un chunk comune e ogni route lo importa da lì.

Il code splitting peggiora le metriche di caricamento?

Può peggiorare l'LCP se il contenuto principale è dentro un chunk caricato tardi. Tieni nell'entry ciò che disegna il primo schermo e separa il resto.