Faça sua pergunta e obtenha um resumo do documento referenciando esta página e o provedor AI de sua escolha
O conteúdo desta página foi traduzido com uma IA.
Veja a última versão do conteúdo original em inglêsSe você tiver uma ideia para melhorar esta documentação, sinta-se à vontade para contribuir enviando uma pull request no GitHub.
Link do GitHub para a documentaçãoCopiar o Markdown do documento para a área de transferência
vue-i18n VS @intlayer/vue-i18n | Mesma API, Bundle Diferente
@intlayer/vue-i18n é um adaptador de compatibilidade: expõe a API vue-i18n (createI18n, useI18n, t(), d(), n(), $t, v-t, i18n.global.locale...) e a serve a partir de dicionários compilados pelo Intlayer. Seus arquivos .vue não mudam. O que t("footer.github") está vinculado é que muda.
Este artigo mede essa troca na mesma aplicação Vite + Vue 3, construída uma vez com vue-i18n e outra com o adapter. Os números vêm de Benchmark Bloom. Para vue-i18n e Intlayer comparados como bibliotecas, leia vue-i18n vs Intlayer e o benchmark vue-i18n vs Intlayer. Este é sobre o que o adapter muda quando você mantém seus componentes como estão.
tl;dr: Na mesma aplicação Vite + Vue 3, substituirvue-i18npor@intlayer/vue-i18nreduziu o JavaScript por página de 134.9 KB para 47.0 KB gzip (a app sem i18n pesa 41.3 KB), o runtime de 24.3 KB para 7.9 KB, o componente médio de 196 KB para 8.4 KB, e o vazamento de strings de páginas estrangeiras de 90% para 0%, sem editar nenhum arquivo.vue.createI18n({ messages })continua funcionando como fallback; remova as importações JSON para obter os números acima. Blocos SFC<i18n>esetLocaleMessage()em runtime são as duas features que não são transportadas.
O que é @intlayer/vue-i18n
vue-i18n é um runtime. createI18n({ messages: { en, fr, ... } }) constrói uma instância global contendo todas as mensagens de todos os locales; useI18n() vincula cada componente a ela; t("footer.github") percorre a árvore em tempo de renderização. Esse design é o que torna os blocos SFC <i18n> e setLocaleMessage() possíveis, e é também por isso que o gráfico de dependências de cada componente inclui a árvore inteira.
@intlayer/vue-i18n mantém a API e substitui a árvore:
- Import aliasing.
vueI18nVitePlugin()de@intlayer/vue-i18n/pluginenvolvevite-intlayere adiciona umresolve.aliaspara quevue-i18nseja resolvido para@intlayer/vue-i18n. Nenhuma importação é renomeada. - JSON como fonte da verdade. O plugin
syncJSONlê seulocales/{locale}.jsonexistente comformat: "vue-i18n"(para que{name},{0}interpolação de lista e"car | cars"plurais com pipe sejam analisados corretamente) e escreve traduções de volta quando a CLI ou o CMS as atualiza. - Call-site binding. A passagem de otimização do Intlayer reescreve os locais de chamada
useI18n()para que o componente receba os dicionários nomeados por suas chaves, na locale ativa, como imports que o bundler pode rastrear e dividir.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
O componente não alcança mais a árvore global de mensagens. Ele alcança footer. É por isso que a coluna de tamanho do componente abaixo cai de 196 KB para 8 KB.
O que o adaptador mantém, ignora e não substitui
Abrir a tabela em um modal para ver todo o conteúdo claramente
vue-i18n API | Com @intlayer/vue-i18n |
|---|---|
useI18n() → { t, d, n, te, tm, rt, locale, availableLocales } | ✅ Mantido. As chaves de t são digitadas em relação aos seus dicionários |
t("key", { name }), t("key", [a, b]), t("key", count) | ✅ Mantido. {name}, {0} e plurais separados por pipe são resolvidos como antes |
d(date, "long"), n(value, "currency") | ✅ Mantido. datetimeFormats / numberFormats de createI18n() são respeitados, apoiados pelo Intl nativo |
i18n.global.locale.value = "fr" | ✅ Mantido. Uma WritableComputedRef apoiada pelo cliente Intlayer; a reatividade funciona como antes |
$t, $tc, $te, $tm, $rt, $d, $n, $i18n (Options API) | ✅ Mantido. Registrado em app.config.globalProperties por app.use(i18n) |
v-t directive | ✅ Mantido |
legacy: true | ✅ Aceito |
createI18n({ messages }) | ⚠️ messages são usados como um fallback em runtime com um aviso de dev. Remova as importações JSON para ganhos no bundle |
setLocaleMessage(), mergeLocaleMessage() | ❌ Aviso e sem ação. O carregamento de mensagens em runtime é substituído por dicionários em build-time |
SFC <i18n> custom blocks | ❌ Não lido. Mova essas mensagens para o JSON de locale (ou um .content.ts próximo ao componente) |
@nuxtjs/i18n | ⚠️ Adapter separado, veja a documentação de compatibilidade Nuxt |
O benchmark
O que foi medido
O Benchmark Bloom suite constrói a mesma aplicação Vite + Vue 3 com cada setup: 10 páginas (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 locales (en, fr, es, de, it, pt, zh, ja, ko, ru), componentes idênticos e conteúdo idêntico. As páginas são medidas em en e fr.
Ambas foram construídas na configuração static, a que a maioria dos projetos Vue faz deploy: para vue-i18n, todo o JSON de cada locale é importado e passado para createI18n({ messages }); para o adapter, os mesmos componentes com vite.config.ts e intlayer.config.ts alterados e a importação de messages removida. O vue-intlayer nativo é incluído como referência.
Para cada build, a suite registra:
- Tamanho da lib: tamanho gzip (e minificado) de um componente vazio que apenas importa a biblioteca i18n.
- Page JS: JavaScript gzip baixado por página, média de todas as páginas e locales.
- Locale leak %: compartilhamento de strings traduzidas no JS baixado que pertencem a um locale que o usuário não está visualizando.
- Page leak %: compartilhamento de strings traduzidas no JS baixado que pertencem a uma página em que o usuário não está.
- Component avg: tamanho gzip médio de cada componente compilado isoladamente.
- E2E reactivity: tempo decorrido entre selecionar uma nova locale e
html[lang]ser atualizado no DOM (Playwright, 5 iterações). - Page load:
PerformanceNavigationTiming.duration.
Os números abaixo vêm da execução datada de 2026-09-12 comvue-i18n11.4.0 e@intlayer/vue-i18n9.5.1. A aplicação de teste é deliberadamente pequena (algumas dezenas de strings por locale), então as porcentagens de vazamento descrevem um padrão: elas crescem com seu conteúdo enquanto o custo de runtime permanece fixo.
Resultados em Vite + Vue 3
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Setup | Strategy | Lib size (gz) | Lib size (min) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Page load |
|---|---|---|---|---|---|---|---|---|---|
| base (sem 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 |
@intlayer/vue-i18n | static | 7.9 KB | 23.2 KB | 47.0 KB | 15.0% | 0.0% | 8.4 KB | 1.5 ms | 9.3 ms |
vue-intlayer (nativo) | static | 3.9 KB | 11.1 KB | 57.1 KB | 56.8% | 0.0% | 7.7 KB | 4.5 ms | 13.8 ms |
vue-intlayer (native) | dynamic | 3.9 KB | 11.1 KB | 59.8 KB | 50.0% | 0.0% | 6.5 KB | 4.0 ms | 15.8 ms |
A coluna page-leak da aplicação base é deixada em branco: sem biblioteca i18n, a coleta de impressões digitais detecta strings codificadas em chunks compartilhados e o número não é significativo.
Como ler
- 88 KB a menos por página, mesmos componentes.
vue-i18nleva a aplicação de 41.3 KB para 134.9 KB. O build do adaptador dos mesmos componentes chega a 47.0 KB, 5.7 KB acima da aplicação base. A maior parte da diferença é os 74.9 KB desrc/localesquecreateI18n({ messages })puxa para cada página e o adaptador nunca agrupa como um bloco. - O runtime encolhe 3x. Um componente vazio que apenas importa
vue-i18ncusta 24.3 KB gzip / 83.2 KB minified:@intlify/core-base, o compilador de mensagens e o runtime. O adapter custa 7.9 KB / 23.2 KB, a maior parte sendo o core do Intlayer mais a superfície da APIvue-i18n. - Componentes: 23x menores. Um componente
useI18n()compilado em isolamento tem uma média de 196 KB, porquetestá vinculado à instância que contém todas as mensagens de cada locale. Com o adapter, o mesmo componente tem uma média de 8.4 KB: ele alcança seu próprio dicionário. - Vazamento.
vue-i18nfornece cada locale e as strings de cada página em cada página: 50% de vazamento de locale (nas duas locales com fingerprint; com dez locales agrupadas o desperdício real é maior), 90% de vazamento de página. O adapter reduz o vazamento de página para 0% porque cada componente importa apenas seus dicionários. O vazamento de locale fica em 15% nesta execuçãostatic;importMode: 'dynamic'é a configuração que o remove, e essa configuração não fazia parte desta execução do Vue. - Reatividade e carregamento de página. A troca de locale é barata para ambas (1.5-2.8 ms); o sistema de reatividade do Vue torna isso possível uma vez que as mensagens estão na memória. O carregamento de página vai de 13.6 ms para 9.3 ms, alinhado com 88 KB a menos de JavaScript para fazer parse.
- Sobre as linhas nativas.
vue-intlayernesta execução agrupou cada locale em modostatice chegou a 57.1 KB com um runtime de 3.9 KB; os dicionários sincronizados do adaptador carregavam menos strings de locales estrangeiros, daí a figura mais baixa por página. O runtime nativo permanece o mais leve dos três, e seu modelo.content.tsé onde os blocos SFC<i18n>encontram seu equivalente.
Por que os números se movem
Nada em src/components/ mudou, então os ganhos vêm do que useI18n está vinculado.
Com vue-i18n, a ligação é a instância global. createI18n({ messages: { en, fr, ... } }) é uma importação que contém tudo; cada componente que chama useI18n() pode acessar tudo isso, então o bundler não consegue dividir abaixo da instância. Otimizar significa que você divide en.json por rota, chama setLocaleMessage() em um router guard, e mantém o mapa rota-para-arquivo correto conforme os componentes se movem.
Copiar o código para a área de transferência
Com @intlayer/vue-i18n, a binding é o dicionário. syncJSON transforma cada chave de nível superior de en.json em um dicionário; a passagem de otimização entrega ao componente os que seus nomes de chaves, importando o rastreamento do bundler e dividindo por página.
Copiar o código para a área de transferência
A importação messages em i18n.ts é a única linha a deletar. Isso são 88 KB.
Migração em três passos
Instalar
bashCopiar códigoCopiar o código para a área de transferência
O comando detecta
vue-i18n, instalaintlayer,vue-intlayer,@intlayer/vue-i18ne@intlayer/sync-json-plugin, e preenche previamenteintlayer.config.ts. Mantenhavue-i18ninstalado: é uma peer dependency e fornece os tipos.Aponte Intlayer para seus arquivos de localização
intlayer.config.tsCopiar códigoCopiar o código para a área de transferência
locales/{locale}.jsonpermanece onde está. Cada chave de nível superior (footer,hero...) torna-se um dicionário.Adicionar o plugin e remover a importação de mensagens
vite.config.tsCopiar códigoCopiar o código para a área de transferência
src/i18n.tsCopiar códigoCopiar o código para a área de transferência
vueI18nVitePlugin()encapsulavite-intlayer(observação de conteúdo, compilação de dicionário, a passagem de otimização) e cria um alias devue-i18npara o adaptador. Remover a importação demessagesé o que reduz os 88 KB; deixá-la ativa mantém a aplicação funcionando mas envia ambos.
O que você pode deletar depois
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Arquivo / padrão | Por quê |
|---|---|
import en from "./locales/en.json" e similares | Usado apenas como fallback pelo adapter. É aqui que estava os 88 KB |
setLocaleMessage() em route guards | Sem efeito. O carregamento por rota agora é responsabilidade do compiler |
@intlify/unplugin-vue-i18n | Não necessário: pré-compila mensagens e blocos SFC que o adapter não lê |
Blocos SFC <i18n> | Não são lidos; mova-os para o JSON de locale ou para um .content.ts por componente |
O que você ganha além de bytes
- Chaves tipadas.
t("footer.github")é tipado contra o dicionáriofootercompilado; um caminho incorreto é um erro de TypeScript em vez da chave renderizada como texto. npx intlayer testfalha no CI se houver uma chave faltando em qualquer locale.npx intlayer filltraduz as chaves faltando com sua chave de provider (OpenAI, Anthropic, Mistral, Gemini...) e as escreve de volta emlocales/{locale}.json.- Visual Editor e CMS operam no mesmo JSON, então desenvolvedores não profissionais editam através de uma UI e os arquivos são atualizados.
- Migração incremental para
.content.ts. Qualquer componente pode mudar deuseI18n()parauseIntlayer("footer")com um arquivo de conteúdo co-localizado. Dicionários JSON e.content.tscoexistem e fazem merge.
Limites a conhecer antes de começar
- Blocos SFC
<i18n>não são lidos. Se suas mensagens vivem dentro de componentes, elas precisam se mover para os arquivos de locale (ou para.content.ts, que é a mesma ideia com tipos). - Carregamento de mensagens em runtime acabou.
setLocaleMessage()emergeLocaleMessage()emitem avisos e retornam. Traduções buscadas de um CMS em runtime precisam do CMS do Intlayer, ou dos comandosintlayer pull/push. messagesé um fallback, não é gratuito. Manter as importações JSON emcreateI18n()mantém os 75 KB no bundle. Delete-as assim queintlayer testpassar.- O adaptador não é o runtime nativo. 7.9 KB contra 3.9 KB para
vue-intlayer. Uma vez que todos os componentes migrarem parauseIntlayer, remova-o.
Quando usar qual?
- Mantenha-se em
vue-i18nse sua aplicação depende de blocos SFC<i18n>, de fluxos desetLocaleMessage()em runtime, ou se 90 KB por página não é uma preocupação para seu público. - Use
@intlayer/vue-i18nse você está emvue-i18ne quer os 88 KB, os componentes 23x menores, 0% vazamento de página, chaves tipadas e verificações de CI sem editar um arquivo.vue. Este é o ponto de entrada para um codebasevue-i18nexistente. - Vá nativo (
vue-intlayer) para novos projetos, ou uma vez que o adaptador tenha feito seu trabalho. Ele tem o runtime mais leve (3.9 KB) e o modelo.content.tspor componente que substitui blocos<i18n>com conteúdo tipado.
Comparações relacionadas
- vue-i18n vs Intlayer (recursos e DX)
- vue-i18n vs Intlayer benchmark (as bibliotecas, mesmo benchmark)
- next-intl vs @intlayer/next-intl (mesma série de adaptadores)
- i18next vs @intlayer/i18next (mesma série de adaptadores)
- Lingui vs @intlayer/lingui (mesma série de adaptadores)
- Guia de migração: vue-i18n para Intlayer
- Referência do adaptador de compatibilidade: vue-i18n, Nuxt i18n
Conclusão
@intlayer/vue-i18n muda o que useI18n() está vinculado: de uma instância global contendo todas as mensagens de cada locale para um dicionário compilado para esse componente. No mesmo app Vite + Vue 3 que é 88 KB menor por página, um runtime 3x menor, componentes 23x menores e 0% vazamento de página, para um arquivo de config, uma linha de plugin e um import deletado. Blocos SFC <i18n> e carregamento de mensagens em tempo de execução são as duas coisas que não carrega, e o runtime vue-intlayer nativo permanece com metade do tamanho.
Todos os dados brutos, os aplicativos de teste e os scripts estão no repositório Benchmark Bloom. Execute você mesmo.
Consulte a documentação 'Por que Intlayer?' para mais detalhes.
Comentários
Ainda sem comentários. Seja o primeiro a compartilhar seus pensamentos.
