Pose una domanda e ottieni un riassunto del documento facendo riferimento a questa pagina e al provider AI di tua scelta
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
vue-i18n VS Intlayer: Benchmark di internazionalizzazione (i18n) per Vue
vue-i18n è la libreria i18n di riferimento per Vue. Intlayer è un'alternativa basata su compilatore, con contenuti a scope di componente, con un'integrazione Vue (vue-intlayer). Questo articolo guarda a quanto costa ciascuna una volta che l'app è compilata.
I dati provengono da Benchmark Bloom, una suite open-source che compila la stessa applicazione con ogni libreria e registra ciò che il browser scarica ed esegue davvero.
tl;dr: Sulla stessa app Vite + Vue 3,vue-i18nspedisce 134,9 KB di JavaScript gzippato per pagina contro 41,3 KB per l'app senza i18n. Intlayer spedisce 57,1 KB. Il solo runtime divue-i18npesa 24,3 KB gzip (6x i 3,9 KB di Intlayer), ogni pagina porta con sé il 90% delle stringhe di altre pagine, e un componente compilato in isolamento trascina 196 KB perché è legato all'albero globale dei messaggi. L'adapter@intlayer/vue-i18nmantiene l'API divue-i18ne ha misurato 47,0 KB per pagina.
In breve
- vue-i18n - La libreria i18n de facto per Vue 2 / Vue 3 e il cuore di
@nuxtjs/i18n. Messaggi in stile ICU, blocchi<i18n>negli SFC, direttivav-t, formatterd()/n(), ampio ecosistema. I messaggi sono registrati su un'istanza globale increateI18n(); il lazy loading per locale è un pattern manuale consetLocaleMessage(), e la suddivisione per route va costruita da voi. - Intlayer - Modello di contenuto centrato sui componenti. I dizionari
.content.tsstanno accanto al componente che servono, un compilatore build-time (vite-intlayer) fa tree-shaking e lazy loading per componente e per locale, i tipi TypeScript stretti vengono generati dal vostro contenuto, e le traduzioni mancanti falliscono in fase di build. Include helper per router / SEO, un Visual Editor / CMS e traduzione assistita da IA.
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
I badge si aggiornano automaticamente. Le istantanee varieranno nel tempo.
Confronto delle funzionalità fianco a fianco
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
| Funzionalità | vue-intlayer (Intlayer) | vue-i18n |
|---|---|---|
| Traduzioni vicino ai componenti | ✅ Sì, .content.ts co-locato con ogni componente | ✅ Tramite blocchi SFC <i18n> (opzionale); i cataloghi globali sono la norma |
| Integrazione TypeScript | ✅ Tipi stretti auto-generati dal contenuto | ✅ Buone tipizzazioni; la sicurezza stretta delle chiavi richiede schema e disciplina |
| Rilevamento traduzioni mancanti | ✅ Errore TypeScript + errore/avviso in fase di build | ⚠️ Fallback a runtime + avviso in console |
| Contenuti ricchi (componenti / Markdown) | ✅ Supporto diretto | ⚠️ Interpolazione di componenti <i18n-t>; Markdown tramite plugin esterni |
| Supporto ICU | ⚠️ In corso | ✅ Sì |
| Formattazione (date, numeri, valute) | ✅ Formatter basati su Intl | ✅ d() / n() con datetimeFormats / numberFormats |
| Routing localizzato | ✅ Helper per Vue Router / Nuxt, getMultilingualUrls | ⚠️ Non nel core (@nuxtjs/i18n o configurazione router custom) |
| Helper SEO (hreflang, sitemap, robots) | ✅ Helper integrati | ❌ Non nel core |
| Tree-shaking (spedire solo il contenuto usato) | ✅ Per componente, per locale, automatizzato dal compilatore | ⚠️ Manuale: dividere i cataloghi, setLocaleMessage() per route |
| Lazy loading | ✅ importMode: 'dynamic' (una riga di config) | ✅ import() manuale + setLocaleMessage() |
| Purge dei contenuti inutilizzati | ✅ I dizionari morti vengono eliminati in fase di build | ❌ Non integrato |
| Test delle traduzioni mancanti (CLI / CI) | ✅ npx intlayer content test | ⚠️ Di terze parti (vue-i18n-extract) |
| Traduzione con IA | ✅ Integrata, usa le vostre chiavi del provider | ❌ No |
| Visual Editor / CMS | ✅ Visual Editor gratuito + CMS opzionale | ❌ No (piattaforme di localizzazione esterne) |
| Server MCP e Agent Skills | ✅ Sì | ❌ No |
| Ecosistema / community | ⚠️ Più piccolo ma in rapida crescita | ✅ Ampio e maturo nell'ecosistema Vue |
Il benchmark
Cosa è stato misurato
La suite Benchmark Bloom compila la stessa applicazione Vite + Vue 3 con ogni libreria: 10 pagine (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 locale (en, fr, es, de, it, pt, zh, ja, ko, ru), componenti identici e contenuti identici. Le pagine sono misurate in en e fr.
Entrambe le librerie sono state testate nella configurazione static, quella che la maggior parte dei progetti Vue spedisce: per vue-i18n, il JSON di ogni locale importato e passato a createI18n({ messages }); per Intlayer, l'importMode: 'static' predefinito. In quella modalità anche Intlayer include tutte le locale, ma il compilatore continua a limitare il contenuto per componente, quindi una pagina porta solo i dizionari dei componenti che renderizza.
Per ogni build, la suite registra:
- Lib size: dimensione gzip di un componente vuoto che importa solo la libreria i18n. Il costo fisso del runtime.
- Page JS: JavaScript gzip scaricato per pagina, in media su tutte le pagine e le locale.
- Locale leak %: quota di stringhe tradotte trovate nel JS scaricato che appartengono a una locale che l'utente non sta visualizzando (fingerprint su
enefr, quindi 50% significa "l'altra locale misurata è completamente presente"; con 10 locale incluse, lo spreco reale è maggiore). - Page leak %: quota di stringhe tradotte trovate nel JS scaricato che appartengono a una pagina in cui l'utente non si trova.
- Component avg: dimensione gzip media di ogni componente compilato in isolamento. Mostra quanto runtime i18n e catalogo trascina un singolo componente.
- E2E reactivity: tempo reale tra la selezione di una nuova locale e l'aggiornamento di
html[lang]nel DOM (Playwright, 5 iterazioni). - Page load:
PerformanceNavigationTiming.duration.
I numeri qui sotto provengono dall'esecuzione datata 2026-09-12 convue-i18n11.4.0 eintlayer9.5.0 / 9.5.1. L'applicazione di test è deliberatamente piccola (qualche decina di stringhe per locale), quindi le percentuali di leakage descrivono un pattern: crescono con i vostri contenuti mentre il costo del runtime resta fisso.
Risultati su Vite + Vue 3
Scegli le metriche e le librerie che ti interessano:
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
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
| Libreria | Strategia | Lib size (gz) | Lib size (min) | Page JS media (gz) | Locale leak | Page leak | Component media (gz) | Reattività E2E | Page load |
|---|---|---|---|---|---|---|---|---|---|
| base (senza i18n) | - | 0,0 KB | 0,0 KB | 41,3 KB | 0,0% | - | 1,1 KB | 1,8 ms | 10,8 ms |
vue-i18n | static | 24,3 KB | 83,2 KB | 134,9 KB | 50,0% | 90,0% | 196,0 KB | 2,8 ms | 13,6 ms |
vue-intlayer | static | 3,9 KB | 11,1 KB | 57,1 KB | 56,8% | 0,0% | 7,7 KB | 4,5 ms | 13,8 ms |
@intlayer/vue-i18n (compat) | static | 7,9 KB | 23,2 KB | 47,0 KB | 15,0% | 0,0% | 8,4 KB | 1,5 ms | 9,3 ms |
La colonna page-leak dell'app base è lasciata vuota: senza libreria i18n, il fingerprinting rileva stringhe hard-coded nei chunk condivisi e il numero non è significativo.
Come leggerlo
- Costo del runtime.
vue-i18nè uno dei runtime più pesanti dell'intero benchmark: 24,3 KB gzip / 83,2 KB minificato per un componente vuoto che lo importa soltanto.vue-intlayercosta 3,9 KB gzip. Quel divario si paga su ogni pagina, indipendentemente da quante stringhe avete. - JavaScript per pagina. L'app senza i18n pesa 41,3 KB.
vue-i18nla più che triplica a 134,9 KB; Intlayer si ferma a 57,1 KB, +15,8 KB, per lo più dovuti alle dieci locale incluse (vedi il punto successivo). - Leakage. Con
createI18n({ messages: { en, fr, ... } }), ogni pagina spedisce tutte le locale e le stringhe di tutte le pagine: 50% di locale leakage (sulle due locale con fingerprint) e 90% di page leakage. La modalitàstaticdi Intlayer include anche tutte le locale (da qui il dato di locale leak comparabile) ma ha 0% di page leakage: una pagina tira solo i dizionari dei componenti che renderizza. Passare aimportMode: 'dynamic'rimuove anche il locale leakage; quella configurazione non faceva parte di questa esecuzione Vue. - La dimensione dei componenti è dove l'architettura si vede. Un componente che chiama
useI18n()compila a 196 KB in media, perchét()è legato all'istanza globale che contiene ogni messaggio di ogni locale. Lo stesso componente conuseIntlayer()compila a 7,7 KB: raggiunge solo il proprio dizionario. - La reattività non è un problema per nessuno dei due (2-5 ms). Il sistema di reattività di Vue rende economico il cambio di locale una volta che i messaggi sono in memoria.
@intlayer/vue-i18n, l'adapter drop-in, mantiene l'API divue-i18ne ha misurato 47,0 KB per pagina e 8,4 KB per componente, con il codice applicativo intatto.
Per riferimento, la stessa esecuzione ha misurato fluent-vue a 171,8 KB per pagina, 29,7 KB di runtime e 217 KB per componente.
Tabella completa, con tutte le librerie e tutte le strategie, nel report del benchmark Vue.
Perché il divario? Istanza globale vs dizionari compilati
vue-i18n è un runtime. createI18n() costruisce un'istanza globale che contiene un albero di messaggi per locale; useI18n() lega ogni componente a essa; t("footer.github") cerca la chiave al momento del render. È ciò che rende possibili i blocchi SFC <i18n>, v-t e il caricamento dei messaggi a runtime, ed è anche il motivo per cui il grafo delle dipendenze di ogni componente include l'intero albero:
Copiare il codice nella clipboard
Ottimizzare significa che voi dividete en.json in file per route, voi chiamate setLocaleMessage() in un guard del router, e voi mantenete corretta la mappa route-file man mano che i componenti si spostano. Il runtime non può farlo per voi perché non ha idea di quali chiavi chiederà un componente.
Intlayer sposta quella conoscenza nella build. Il contenuto è dichiarato accanto al componente, e vite-intlayer risolve quale componente importa quale dizionario:
Copiare il codice nella clipboard
Il compilatore emette, per dizionario e per locale, esattamente il JSON di cui quel componente ha bisogno, ed elimina i dizionari che nessuno importa. Lo scope per route è una conseguenza dello scope per componente, non un compito.
Per eliminare anche le locale inutilizzate, impostatedictionary.importMode: 'dynamic'inintlayer.config.ts. Vedi la doc sull'ottimizzazione del bundle.
Developer experience
Setup
vue-i18n
Copiare il codice nella clipboard
Copiare il codice nella clipboard
Intlayer
Copiare il codice nella clipboard
Copiare il codice nella clipboard
Copiare il codice nella clipboard
Componente
vue-i18n
Copiare il codice nella clipboard
Copiare il codice nella clipboard
t('counter.label') è una stringa finché non tipizzate voi stessi lo schema dei messaggi; un errore di battitura renderizza la chiave.
Intlayer
Copiare il codice nella clipboard
Copiare il codice nella clipboard
label e increment sono tipizzati; un errore di battitura è un errore TypeScript, un valore francese mancante è un errore di build.
Lazy loading per locale
vue-i18n
Copiare il codice nella clipboard
Poi chiamate loadLocaleMessages() da un guard del router, e dividete voi stessi locales/{locale}.json per route se volete uno scope per pagina.
Intlayer
Copiare il codice nella clipboard
Mantenete l'API di vue-i18n, ottenete l'output di Intlayer
@intlayer/vue-i18n è un adapter drop-in: useI18n(), t(), d(), n(), l'interpolazione {name} e {0}, i plurali con pipe ("car | cars"), v-t e i18n.global.locale continuano a funzionare, serviti da dizionari Intlayer compilati da vite-intlayer.
Copiare il codice nella clipboard
Nel benchmark, la build compat della stessa app è passata da 134,9 KB a 47,0 KB per pagina e da 196 KB a 8,4 KB per componente, con i componenti intatti. I vostri locales/{locale}.json esistenti possono restare la fonte di verità tramite il plugin di sincronizzazione JSON.
Vedi la guida di migrazione da vue-i18n e la doc di compatibilità. Gli utenti Nuxt hanno lo stesso percorso tramite la compatibilità @nuxtjs/i18n.
Quando scegliere quale?
- Scegliete vue-i18n se volete l'approccio Vue standard, vi affidate ai messaggi ICU o ai blocchi SFC
<i18n>, usate già@nuxtjs/i18n, o una piattaforma di traduzione si aspetta JSON centralizzato. Mettete in conto il tempo per dividere i cataloghi e fare lazy loading per route se la dimensione del bundle conta. - Scegliete Intlayer se volete contenuti a scope di componente, TypeScript stretto, errori di chiavi mancanti in fase di build, tree-shaking e lazy loading senza sforzo, e strumenti editoriali integrati (Visual Editor, CMS, traduzione IA, server MCP). Particolarmente rilevante per codebase Vue / Nuxt grandi e modulari e per i design system.
- Scegliete
@intlayer/vue-i18nse siete già suvue-i18ne volete i guadagni sul bundle senza una riscrittura.
FAQ
Entrambi, a seconda di come lo adotti. vue-intlayer è un runtime nativo con il proprio composable useIntlayer(). @intlayer/vue-i18n è un adattatore di compatibilità che mantiene l'API di vue-i18n sostituendo ciò a cui è vincolata, permettendoti di migrare senza modificare i componenti e procedere file per file successivamente.
L'adattatore non li legge. Sposta quei messaggi nei tuoi file JSON di lingua, o in un file .content.ts accanto al componente, che rappresenta la stessa idea con tipi generati. Questa è l'unica funzionalità di vue-i18n non supportata.
Sì. Intlayer con Nuxt copre routing multilingue, middleware di rilevamento della lingua e generazione di sitemap. Se usi @nuxtjs/i18n, l'adattatore di compatibilità Nuxt i18n è il percorso di migrazione.
Sì. Il plugin di sincronizzazione JSON li legge con il dialetto vue-i18n ({name}, {0}, plurali pipe "car | cars") e scrive le traduzioni quando la CLI o il CMS li aggiorna.
Il supporto nativo ICU è in fase di sviluppo. L'adattatore @intlayer/vue-i18n gestisce la sintassi propria di vue-i18n, inclusi i plurali pipe e l'interpolazione denominata e di elenchi. Per il modello di pluralizzazione di Intlayer, consulta il contenuto di enumerazione.
Confronti correlati
Documentazione di riferimento:
Report del benchmark:
Per capire da dove vengono queste librerie, leggi la storia dell'i18n in JavaScript.
Stelle GitHub
Le stelle GitHub sono un forte indicatore della popolarità di un progetto, della fiducia della community e della rilevanza a lungo termine. Pur non essendo una misura diretta della qualità tecnica, riflettono quanti sviluppatori trovano utile il progetto, ne seguono i progressi e sono propensi ad adottarlo.
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
- 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
- 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.
Conclusione
vue-i18n è maturo, flessibile e profondamente integrato con Vue. Il benchmark mostra cosa costa il suo design runtime-first su una build Vite: un runtime di 24 KB gzip, 134,9 KB per pagina per un'app che pesa 41 KB senza i18n, 90% di contenuti di altre pagine su ogni pagina, e componenti che raggiungono ciascuno 196 KB perché dipendono dall'albero globale dei messaggi.
Intlayer sposta il lavoro nel compilatore. I dizionari per componente e la purge dei contenuti morti sono output della build, non convenzioni. Sulla stessa app: 3,9 KB di runtime, 57,1 KB per pagina, 0% di page leakage, componenti 25x più piccoli. E se una riscrittura non è un'opzione, @intlayer/vue-i18n fa gran parte della strada con i componenti intatti.
Tutti i dati grezzi, le app di test e gli script sono nel repository Benchmark Bloom. Eseguitelo voi stessi.
Consultate la doc "Perché Intlayer?" per maggiori dettagli.
Commenti
Ancora nessun commento. Sii il primo a condividere i tuoi pensieri.
