使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
vue-i18n VS @intlayer/vue-i18n | 相同的 API,不同的 Bundle

@intlayer/vue-i18n 是一个兼容适配器:它公开了 vue-i18n API(createI18n、useI18n、t()、d()、n()、$t、v-t、i18n.global.locale...),并从 Intlayer 编译的字典中提供服务。你的 .vue 文件不会改变。改变的是 t("footer.github") 绑定的内容。
本文在同一个 Vite + Vue 3 应用上测量了这个替换,该应用分别使用 vue-i18n 和适配器构建。数据来自 Benchmark Bloom。如需了解 vue-i18n 和 Intlayer 作为库的对比,请阅读 vue-i18n vs Intlayer 和 vue-i18n vs Intlayer 基准测试。本文讨论的是当你保持组件不变时,适配器会带来什么改变。
总结: 在同一个 Vite + Vue 3 应用中,将vue-i18n替换为@intlayer/vue-i18n后,每页 JavaScript 从 134.9 KB 降至 47.0 KB gzip(不含 i18n 的应用为 41.3 KB),运行时从 24.3 KB 降至 7.9 KB,平均组件从 196 KB 降至 8.4 KB,跨页面字符串泄露从 90% 降至 0%,且无需编辑任何.vue文件。createI18n({ messages })仍作为备选方案继续工作;移除 JSON 导入即可获得上述数字。SFC<i18n>块和运行时setLocaleMessage()这两个功能无法转移。
什么是 @intlayer/vue-i18n
vue-i18n 是一个运行时库。createI18n({ messages: { en, fr, ... } }) 构建一个全局实例,持有每个区域的所有消息;useI18n() 将每个组件绑定到它;t("footer.github") 在渲染时遍历树。这种设计使得 SFC <i18n> 块和 setLocaleMessage() 成为可能,同时也是为什么每个组件的依赖图包含整个树的原因。
@intlayer/vue-i18n 保持 API 并替换树:
- 导入别名。
@intlayer/vue-i18n/plugin中的vueI18nVitePlugin()包装vite-intlayer并添加一个resolve.alias,使得vue-i18n解析为@intlayer/vue-i18n。没有导入被重命名。 - JSON 作为真实来源。
syncJSON插件读取你现有的locales/{locale}.json(使用format: "vue-i18n",以便正确解析{name}、{0}列表插值和"car | cars"管道复数),当 CLI 或 CMS 更新它们时,会将翻译写回。 - 调用点绑定。 Intlayer 优化通过重写
useI18n()调用点,使组件接收其键名在活跃locale中的字典,作为bundler可以追踪和分割的imports。
复制代码到剪贴板
复制代码到剪贴板
该组件不再访问全局消息树。它只访问 footer。这就是为什么下面的组件大小列从 196 KB 下降到 8 KB。
adapter 保留、忽略和不替换的内容
在弹窗中打开表格以清晰地查看所有数据
vue-i18n API | 使用 @intlayer/vue-i18n |
|---|---|
useI18n() → { t, d, n, te, tm, rt, locale, availableLocales } | ✅ 保留。t 键针对你的字典进行了类型化 |
t("key", { name }), t("key", [a, b]), t("key", count) | ✅ 保留。{name}、{0} 和管道分隔的复数形式解析方式与以前相同 |
d(date, "long"), n(value, "currency") | ✅ 保留。来自 createI18n() 的 datetimeFormats / numberFormats 得到遵守,由原生 Intl 提供支持 |
i18n.global.locale.value = "fr" | ✅ 保留。由 Intlayer 客户端支持的 WritableComputedRef;响应式行为与之前相同 |
$t, $tc, $te, $tm, $rt, $d, $n, $i18n(Options API) | ✅ 保留。由 app.use(i18n) 注册到 app.config.globalProperties |
v-t 指令 | ✅ 保留 |
legacy: true | ✅ 接受 |
createI18n({ messages }) | ⚠️ messages 被用作运行时 fallback,并会有开发警告。移除 JSON imports 以获得 bundle 优化 |
setLocaleMessage(), mergeLocaleMessage() | ❌ 警告并不执行任何操作。运行时消息加载被构建时字典替代 |
SFC <i18n> 自定义块 | ❌ 不被读取。将这些消息移入 locale JSON(或组件旁的 .content.ts) |
@nuxtjs/i18n | ⚠️ 独立适配器,请查看 Nuxt 兼容性文档 |
基准测试
测量了什么
Benchmark Bloom 套件使用相同的 Vite + Vue 3 应用程序构建每个设置:10 个页面(home、about、blog、careers、contact、FAQ、pricing、products、settings、team),10 个语言环境(en、fr、es、de、it、pt、zh、ja、ko、ru),相同的组件和相同的内容。页面在 en 和 fr 中进行测量。
两者都以静态配置构建,这是大多数 Vue 项目使用的配置:对于 vue-i18n,每个语言环境的 JSON 导入并传递给 createI18n({ messages });对于适配器,使用相同的组件,改变 vite.config.ts 和 intlayer.config.ts 并移除 messages 导入。包含原生 vue-intlayer 作为参考。
对于每个构建,套件记录:
- Lib size: 空组件的 gzip(和压缩后)大小,该组件仅导入 i18n 库。
- Page JS: 每个页面下载的 gzip JavaScript,在所有页面和语言环境中平均。
- Locale leak %: 下载的 JS 中属于用户未查看的语言环境的已翻译字符串的份额。
- Page leak %: 下载的 JS 中属于用户未访问的页面的已翻译字符串的份额。
- Component avg: 单独编译的每个组件的平均 gzip 大小。
- E2E reactivity: 选择新语言环境和
html[lang]在 DOM 中更新之间的实际时间(Playwright,5 次迭代)。 - Page load:
PerformanceNavigationTiming.duration。
下面的数字来自 2026-09-12 运行的数据,使用vue-i18n11.4.0 和@intlayer/vue-i18n9.5.1。测试应用程序故意很小(每个语言环境只有几十个字符串),所以泄露百分比描述的是一个模式:当你的内容增加时,泄露会增长,但运行时成本保持不变。
Vite + Vue 3 的结果
选择您关注的指标和库:
动态 JSON 加载
在运行时懒加载翻译
有作用域的 JSON (命名空间)
每页翻译命名空间
I18n 性能基准测试
这个指标是什么?
国际化库包的总 gzip 压缩大小。它仅包含 tree-shaking 和压缩(minification)后的提供者(provider)和内容检索逻辑。
为什么这很重要?
较小的库大小可减少初始 JavaScript 负载,从而缩短客户端的下载和执行时间。
视图形式
在弹窗中打开表格以清晰地查看所有数据
| Setup | Strategy | Lib size (gz) | Lib size (min) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Page load |
|---|---|---|---|---|---|---|---|---|---|
| base (no 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 (native) | 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 |
基础应用的页面泄漏列为空:没有 i18n 库,指纹识别会在共享块中挑选硬编码的字符串,该数字没有意义。
如何理解它
- 每个页面减少 88 KB,组件相同。
vue-i18n将 41.3 KB 的应用增加到 134.9 KB。相同组件的适配器构建落在 47.0 KB,比基础应用多 5.7 KB。大多数差异来自createI18n({ messages })将 74.9 KB 的src/locales拉入每个页面,而适配器从不将其作为一个块捆绑。 - 运行时缩小 3 倍。 仅导入
vue-i18n的空组件成本为 24.3 KB gzip / 83.2 KB minified:@intlify/core-base、message compiler 和 runtime。adapter 成本为 7.9 KB / 23.2 KB,大部分是 Intlayer 的 core 加上vue-i18nAPI surface。 - 组件:小 23 倍。 单独编译的
useI18n()组件平均为 196 KB,因为t绑定到持有每个 locale 所有消息的实例。使用 adapter,相同的组件平均为 8.4 KB:它到达自己的字典。 - 泄漏。
vue-i18n在每个页面上都会打包每个语言环境和每个页面的字符串:50% 的语言环境泄漏(在两个指纹识别的语言环境上;捆绑十个语言环境时实际浪费更高),90% 的页面泄漏。该适配器将页面泄漏降低到 0%,因为每个组件只导入其自己的字典。在这次static运行中,语言环境泄漏为 15%;importMode: 'dynamic'是移除它的设置,该配置不在此 Vue 运行中。 - 响应性和页面加载。 对于两者而言,语言环境切换成本低廉(1.5-2.8 ms);一旦消息在内存中,Vue 的响应性系统会实现这一点。页面加载从 13.6 ms 降低到 9.3 ms,与减少 88 KB 的 JavaScript 解析量一致。
- 关于原生行。
vue-intlayer在此运行中在static模式下捆绑了每个区域设置,达到 57.1 KB,运行时为 3.9 KB;适配器的同步字典携带更少的外国语言环境字符串,因此每页数据更低。原生运行时仍然是三者中最轻的,其.content.ts模型是 SFC<i18n>块找到其等效项的地方。
完整表格、各个库及每种策略,请参阅 Vue 基准测试报告。
为什么数字会变化

src/components/ 中的内容没有改变,所以收益来自 useI18n 绑定到的内容。
使用 vue-i18n 时,绑定是全局实例。createI18n({ messages: { en, fr, ... } }) 是一个导入,包含所有内容;每个调用 useI18n() 的组件都可以访问所有内容,因此 bundler 无法在实例以下进行分割。优化意味着 你 需要按路由拆分 en.json,在路由守卫中调用 setLocaleMessage(),并在组件移动时保持路由到文件的映射正确。 浪费在页面和语言两个维度上同时增长:

复制代码到剪贴板
使用 @intlayer/vue-i18n,绑定是字典。syncJSON 将 en.json 的每个顶级键转换为字典;优化过程将组件所需的那些作为导入提供给 bundler 追踪并按页面拆分。
复制代码到剪贴板
i18n.ts 中的 messages 导入是唯一需要删除的一行。那就是 88 KB。
分三个步骤迁移
安装
bash复制代码复制代码到剪贴板
该命令检测
vue-i18n,安装intlayer、vue-intlayer、@intlayer/vue-i18n和@intlayer/sync-json-plugin,并预填充intlayer.config.ts。保持vue-i18n已安装:它是一个对等依赖项,并提供类型。将 Intlayer 指向您的 locale 文件
intlayer.config.ts复制代码复制代码到剪贴板
locales/{locale}.json保持在原来的位置。每个顶级键(footer、hero...)都会变成一个字典。添加插件并删除消息导入
vite.config.ts复制代码复制代码到剪贴板
src/i18n.ts复制代码复制代码到剪贴板
vueI18nVitePlugin()包装了vite-intlayer(内容监听、字典编译、优化过程)并将vue-i18n别名指向适配器。移除messages导入是减少 88 KB 的关键;保留它会使应用继续工作,但会同时发送两个版本。
之后可以删除的内容
在弹窗中打开表格以清晰地查看所有数据
| 文件 / 模式 | 原因 |
|---|---|
import en from "./locales/en.json" 及类似语句 | 仅由适配器用作回退方案。这是 88 KB 的来源 |
路由守卫中的 setLocaleMessage() | 无操作。按路由加载现在是编译器的工作 |
@intlify/unplugin-vue-i18n | 不需要:它预编译消息和 SFC blocks,而适配器不读取这些内容 |
SFC <i18n> 块 | 未被读取;将它们移动到 locale JSON 或每个组件的 .content.ts |
除了字节数之外你还能获得什么
- 类型化的键。
t("footer.github")针对编译的footer字典进行类型检查;错误的路径会产生 TypeScript 错误,而不是将键呈现为文本。 npx intlayer test在 CI 中对任何 locale 中缺少的键失败。npx intlayer fill使用你自己的提供商密钥(OpenAI、Anthropic、Mistral、Gemini...)翻译缺少的键,并将其写回locales/{locale}.json。- Visual Editor 和 CMS 操作相同的 JSON,因此非开发人员可以通过 UI 进行编辑,文件会自动更新。
- 逐步迁移到
.content.ts。 任何组件都可以通过一个共同位置的内容文件从useI18n()切换到useIntlayer("footer")。JSON 和.content.ts字典可以共存并合并。
开始前需要了解的限制
如果您的消息位于组件内部,则需要将它们移动到语言文件或 .content.ts 中,这具有相同的理念并提供类型支持。
setLocaleMessage() 和 mergeLocaleMessage() 会发出警告并直接返回。在运行时从 CMS 获取的翻译需要使用 Intlayer CMS 或 intlayer pull / push 命令。
在 createI18n() 中保留 JSON 导入会在包中保留 75 KB。一旦 intlayer test 通过,即可将其删除。
vue-intlayer 仅 3.9 KB,而适配器为 7.9 KB。一旦所有组件都迁移到 useIntlayer,即可将其移除。
何时使用哪个?
您的应用依赖于 SFC <i18n> 块、运行时 setLocaleMessage() 流程,或者每页 90 KB 对您的用户群而言并不是问题。
您正在使用 vue-i18n,希望在不修改任何 .vue 文件的前提下节省 88 KB、实现组件体积缩小 23 倍、0% 页面泄漏、类型化键和 CI 检查。这是现有 vue-i18n 代码库的最佳切入点。
适用于新项目,或在适配器完成过渡任务之后。它具有最轻量的运行时(3.9 KB)以及按组件划分的 .content.ts 模式,用类型化内容取代 <i18n> 块。请从 Intlayer 与 Vue 或 与 Nuxt 开始。
常见问题解答
不需要。基准测试构建仅修改了 vite.config.ts、intlayer.config.ts 以及 src/i18n.ts 中引入 messages 的一行代码。所有 useI18n()、$t、v-t 和 Options API 的调用位置均保持原样。
因为 useI18n() 不再访问全局实例。createI18n({ messages }) 会持有所有语言的全部消息,因此单独编译的组件会拖入 196 KB。使用适配器后,它仅访问自己的字典:8.4 KB。
完全保留。传递给 createI18n() 的 datetimeFormats 和 numberFormats 依然有效,由原生 Intl 提供支持。请参阅日期、时间和数字格式化。
@intlayer/vue-i18n 针对 Vite + Vue。对于 @nuxtjs/i18n,请使用 Nuxt i18n 兼容适配器,原生设置请参阅 Intlayer 与 Nuxt。
可以。任何组件都可以通过同级放置的内容文件从 useI18n() 切换到 useIntlayer("footer")。JSON 和 .content.ts 字典可以并存并合并。
相关比较
同系列适配器:
两两直接对比:
- vue-i18n vs Intlayer, features and DX
- vue-i18n vs Intlayer benchmark
- Is vue-i18n outdated?
- How to pick a Vue i18n library
参考文档:
- Compat adapter: vue-i18n and Nuxt i18n
- 迁移指南:从 vue-i18n 到 Intlayer
- Vue 基准测试报告
- 包体积优化与 Intlayer 编译器
- 可视化编辑器、CMS 与 AI 翻译
总结
@intlayer/vue-i18n 改变了 useI18n() 的绑定方式:从持有每个locale的每条消息的全局实例转变为为该组件编译的字典。在同一个 Vite + Vue 3 应用上,每页减少 88 KB,运行时减少 3倍,组件减少 23倍,页面泄漏 0%,仅需配置文件、一行插件和删除一个导入。SFC <i18n> 块和运行时消息加载是它不支持的两个功能,而原生 vue-intlayer 运行时仍然保持其一半的大小。
所有原始数据、测试应用程序和脚本都在 Benchmark Bloom 仓库 中。自己运行它。
有关更多详细信息,请参考 'Why Intlayer?' 文档。
评论
暂无评论。成为第一个分享您想法的人吧。
