Questa pagina ha un modello di applicazione disponibile.
Pose una domanda e ottieni un riassunto del documento facendo riferimento a questa pagina e al provider AI di tua scelta
Cronologia delle versioni
- "Aggiornamento dei risultati del benchmark"v9.5.1026/09/2026
- "Aggiornamento dei risultati del benchmark e aggiunta di Tolgee"v9.5.723/09/2026
- "Aggiornamento dei risultati del benchmark"v9.5.111/09/2026
- "Aggiungi comparazione delle stelle di GitHub"v8.9.818/05/2026
- "Inizializzazione del benchmark"v8.7.1206/01/2026
Il contenuto di questa pagina è stato tradotto con un'IA.
Vedi l'ultima versione del contenuto originale in ingleseSe hai un’idea per migliorare questa documentazione, non esitare a contribuire inviando una pull request su GitHub.
Collegamento GitHub alla documentazioneCopia il Markdown del documento nella porta-documenti
Librerie i18n per Vue - Rapporto Benchmark 2026
Questa pagina è un rapporto di benchmark per le soluzioni i18n su Vue.
Sommario
Benchmark Interattivo
Metrica
Caricamento JSON dinamico
Carica le traduzioni in modalità lazy durante l'esecuzione
JSON con ambito (namespacing)
Spazi dei nomi di traduzione per pagina
Cos'è questa metrica?
La dimensione totale compressa con gzip del bundle della libreria di internazionalizzazione. Include solo il provider e la logica di recupero dei contenuti dopo il tree-shaking e la minificazione.
Perché è importante?
Una dimensione della libreria più piccola riduce il payload JavaScript iniziale, portando a tempi di download ed esecuzione più rapidi sul client.
Visualizza come
Riferimento dei risultati:
Introduzione
Le soluzioni di internazionalizzazione sono tra le dipendenze più pesanti in un'app Vue. Il rischio principale è l'invio di contenuti non necessari: traduzioni per altre pagine e altre lingue nel bundle di una singola rotta.
Man mano che l'app cresce, questo problema può far esplodere rapidamente il JavaScript inviato al client e rallentare la navigazione.
In pratica, per le implementazioni meno ottimizzate, una pagina internazionalizzata può finire per essere diverse volte più pesante della versione senza i18n.
L'altro impatto riguarda l'esperienza dello sviluppatore (DX): come si dichiara il contenuto, i tipi, l'organizzazione dei namespace, il caricamento dinamico e la reattività al cambio di lingua.
Per capire da dove vengono queste librerie, leggi la storia dell'i18n in JavaScript.
TL;DR
- Intlayer: La soluzione più leggera (v9.5.10) con scoping e caricamento dinamico nativi.
- Tolgee: Caricamento dinamico efficace con zero perdite in modalità dinamica, ma più pesante (~3.0× Intlayer) e privo di type safety a tempo di compilazione.
- vue-i18n: Lo standard del settore con un ricco ecosistema, ma può essere significativamente più pesante e difficile da ottimizzare per il code-splitting in applicazioni di grandi dimensioni.
- fluent-vue: Organizzazione dei messaggi innovativa ma manca di type-safety e risulta essere una soluzione estremamente pesante.
Testa la tua app
Per individuare rapidamente i problemi di leak i18n, puoi provare lo scanner SEO i18n gratuito.
Il problema
Due leve sono essenziali per limitare il costo di un'app multilingue:
- Dividere il contenuto per pagina / namespace per non caricare interi dizionari quando non servono.
- Caricare la lingua corretta in modo dinamico, solo quando necessario.
Comprendere i limiti tecnici di questi approcci:
Caricamento dinamico
Senza caricamento dinamico, la maggior parte delle soluzioni mantiene i messaggi in memoria fin dal primo render, aggiungendo un overhead significativo per le app con molte rotte e lingue.
Con il caricamento dinamico, si accetta un compromesso: meno JS iniziale, ma a volte una richiesta extra quando si cambia lingua.
Divisione dei contenuti (Splitting)
Le sintassi costruite attorno a const { t } = useI18n() + t('a.b.c') sono molto comode ma spesso incoraggiano a mantenere grandi oggetti JSON a runtime. Questo modello rende difficile il tree-shaking a meno che la libreria non offra una reale strategia di divisione per pagina.
Metodologia
Per questo benchmark, abbiamo confrontato le seguenti librerie:
Base App(Nessuna libreria i18n)vue-intlayer(v9.5.10)@intlayer/vue-i18n(v9.5.10)vue-i18n(v11.4.0)fluent-vue(v3.8.2)@tolgee/vue(v7.2.0)
Il framework è Vue con un'app multilingue di 10 pagine e 10 lingue.
Abbiamo confrontato quattro strategie di caricamento:
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
| Strategia | Senza namespace (globale) | Con namespace (scoped) |
|---|---|---|
| Caricamento statico | Static: Tutto in memoria all'avvio. | Scoped static: Diviso per namespace; tutto caricato all'avvio. |
| Caricamento dinamico | Dynamic: Caricamento on-demand per lingua. | Scoped dynamic: Caricamento granulare per namespace e lingua. |
Riepilogo delle strategie
- Static: Semplice; nessuna latenza di rete dopo il caricamento iniziale. Svantaggio: grandi dimensioni del bundle.
- Dynamic: Riduce il peso iniziale (lazy-loading). Ideale quando si hanno molte lingue.
- Scoped static: Mantiene il codice organizzato (separazione logica) senza complesse richieste di rete extra.
- Scoped dynamic: Il miglior approccio per il code splitting e le prestazioni. Minimizza la memoria caricando solo ciò di cui la vista corrente e la lingua attiva hanno bisogno.
Cosa ho misurato:
Ho eseguito la stessa app multilingue in un browser reale per ogni stack, poi ho annotato cosa passava effettivamente sulla rete e quanto tempo richiedevano le operazioni. Le dimensioni sono riportate dopo la normale compressione web, perché è più vicino a ciò che le persone scaricano effettivamente.
Dimensioni della libreria di internazionalizzazione: Dopo il bundling, il tree-shaking e la minificazione, la dimensione della libreria i18n è la dimensione del codice dei provider + composable in un componente vuoto. Non include il caricamento dei file di traduzione. Risponde a quanto è "costosa" la libreria prima che entri in gioco il tuo contenuto.
JavaScript per pagina: Per ogni rotta del benchmark, quanto script viene scaricato dal browser per quella visita, mediato tra le pagine della suite (e tra le lingue). Le pagine pesanti sono pagine lente.
Leak da altre lingue (Leakage): È il contenuto della stessa pagina ma in un'altra lingua che verrebbe caricato per errore nella pagina verificata. Questo contenuto è inutile e dovrebbe essere evitato (es. contenuto della pagina
/fr/aboutnel bundle della pagina/en/about).Leak da altre rotte: La stessa idea per altre schermate nell'app: se i loro testi vengono caricati quando hai aperto solo una pagina (es. contenuto della pagina
/en/aboutnel bundle della pagina/en/contact). Un punteggio alto indica una divisione debole o bundle troppo ampi.Dimensione media del bundle del componente: Gli elementi UI comuni vengono misurati uno alla volta, invece di nascondersi all'interno di un unico numero gigante dell'app. Mostra se l'internazionalizzazione gonfia silenziosamente i componenti quotidiani. Ad esempio, se il tuo componente viene renderizzato di nuovo, caricherà tutti quei dati dalla memoria. Allegare un JSON gigante a qualsiasi componente è come collegare un grande magazzino di dati inutilizzati che rallenterà le prestazioni dei tuoi componenti.
Reattività al cambio lingua: Cambio la lingua usando il controllo dell'app stessa e cronometro quanto tempo passa finché la pagina non è chiaramente cambiata, quello che un visitatore noterebbe.
Lavoro di rendering dopo un cambio di lingua: Un follow-up più preciso: quanto sforzo ha impiegato l'interfaccia per ridisegnarsi per la nuova lingua una volta avviato il cambio. Utile quando il tempo "percepito" e il costo del framework divergono.
Tempo di caricamento iniziale della pagina: Dalla navigazione fino a quando il browser considera la pagina completamente caricata per gli scenari testati. Utile per confrontare gli avvii a freddo.
Tempo di idratazione (Hydration): Il tempo che il client impiega per trasformare l'HTML del server in un'interfaccia interattiva. Un trattino nelle tabelle significa che quella implementazione non ha fornito una cifra di idratazione affidabile in questo benchmark.
Stelle di GitHub
Le stelle di GitHub sono un forte indicatore della popolarità di un progetto, della fiducia della comunità e della pertinenza a lungo termine. Sebbene non siano una misura diretta della qualità tecnica, riflettono quanti sviluppatori trovano il progetto utile, ne seguono i progressi e sono propensi ad adottarlo. Per stimare il valore di un progetto, le stelle aiutano a confrontare la trazione tra le alternative e forniscono approfondimenti sulla crescita dell'ecosistema.
Attività dei commit
Le stelle indicano la popolarità. I commit indicano quanto lavoro viene investito in un progetto. Al momento della scrittura, Intlayer conta circa 7.500 commit, più della maggior parte delle librerie confrontate qui e circa 5 volte più di next-intl o next-i18next.
- intlify/vue-i18n
- fluent-vue/fluent-vue
- tolgee/tolgee-js
- aymericzip/intlayer
Commit sul branch predefinito, fonte: API GitHub.
Intlayer è un monorepo, quindi il totale include ogni pacchetto framework, la CLI e la documentazione. Leggi i commit come un segnale di attività, non di qualità.
Download npm
- vue-i18n
- fluent-vue
- @tolgee/vue
- vue-intlayer
Fonte: API dei download del registro npm.
I download premiano le soluzioni più vecchie, non le migliori. Una libreria pubblicata anni fa viene ancora installata da ogni progetto che l'ha scelta allora, da ogni esecuzione della CI e da ogni pacchetto che ne dipende. Il numero misura l'inerzia più che una scelta attuale.
Gli assistenti IA amplificano l'effetto. next-intl, i18next e vue-i18n sono ovunque nel codice su cui sono stati addestrati, quindi li suggeriscono di default, senza confrontare le alternative. Ogni suggerimento aggiunge download, che alimentano il suggerimento successivo. Confronta sul benchmark, non sul numero di download.
Risultati in dettaglio
1 - Soluzioni da evitare
Nessuna soluzione chiara da evitare nell'ecosistema Vue.
2 - Soluzioni accettabili
(Tolgee) (@tolgee/vue@7.2.0):
Tolgee affronta molti dei problemi menzionati in precedenza, offrendo un caricamento dinamico che elimina con successo le perdite di locale e di pagina (riducendo il JS della pagina a circa 58.8kb). Tuttavia, non fornisce type safety predefinita in fase di compilazione per le chiavi, rendendo più difficile rilevare le chiavi mancanti. Inoltre, l'impatto della libreria è relativamente pesante (~13.8kb, ovvero circa 3.0× vue-intlayer).
(vue-i18n) (vue-i18n@11.4.0):
- vue-i18n è senza dubbio la libreria i18n più utilizzata per Vue, ha molte funzionalità e un ecosistema immenso. Ma sotto il cofano la soluzione è piuttosto pesante. Anche se vue-i18n integra il caricamento pigro dei messaggi, manca di una funzione di scoping. Nel caso di una classica app Vue SPA non ci sono problemi, ma per un'app Nuxt, utilizzando @nuxt/i18n, ciò porta a includere i messaggi di tutte le pagine in una sola. Per una grande app Nuxt con più di 10 pagine, può diventare davvero problematico.
Il pacchetto è molto pesante (~24.1 kb, circa 6 volte vue-intlayer).
(fluent-vue) (fluent-vue@3.8.2):
- fluent-vue offre un tentativo di innovazione attraverso il formato .ftl. L'organizzazione dei messaggi è ottima, più facile per iniziare. Ma in pratica, la mancanza di type-safety aumenta il rischio di errore e può diventare rapidamente dispendioso in termini di tempo per il debug. Inoltre, questa soluzione carica i messaggi tramite un plugin vite che forza il caricamento di tutto il contenuto in tutte le lingue in ogni pagina. Inoltre, è una soluzione estremamente pesante (~92.7kb, circa 7.5 volte
vue-intlayer).
3 - Raccomandazioni
(Intlayer) (vue-intlayer@9.5.10):
Non giudicherò personalmente vue-intlayer per motivi di obiettività, essendo la mia soluzione.
