使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
vue-i18n VS Intlayer | Vue 国际化 (i18n) 基准测试
vue-i18n 是 Vue 的参考 i18n 库。Intlayer 是一个基于编译器、按组件作用域划分内容的替代方案,并提供 Vue 集成(vue-intlayer)。我们已经比较过它们的功能和开发体验。本文关注的是应用构建完成后,每个库各自的成本。
数据来自 Benchmark Bloom,这是一个开源套件,它用每个库构建同一个应用程序,并记录浏览器实际下载和执行的内容。
tl;dr:在同一个 Vite + Vue 3 应用上,vue-i18n每页交付 134.9 KB 的 gzip 压缩 JavaScript,而无 i18n 的应用为 41.3 KB。Intlayer 交付 57.1 KB。仅vue-i18n的运行时就重达 24.3 KB gzip(是 Intlayer 3.9 KB 的 6 倍),每个页面携带 90% 的其他页面字符串,而单独编译的组件会拖入 196 KB,因为它绑定到全局消息树。@intlayer/vue-i18n适配器保留了vue-i18n的 API,测得每页 47.0 KB。
简而言之
- vue-i18n - Vue 2 / Vue 3 事实上的 i18n 库,也是
@nuxtjs/i18n的核心。ICU 风格的消息、SFC<i18n>块、v-t指令、d()/n()格式化器、庞大的生态系统。消息在createI18n()时注册到全局实例上;按语言的懒加载是手动的setLocaleMessage()模式,按路由拆分需要你自己构建。 - Intlayer - 以组件为中心的内容模型。
.content.ts字典与其服务的组件放在一起,构建时编译器(vite-intlayer)按组件、按语言进行 tree-shaking 和懒加载,从你的内容生成严格的 TypeScript 类型,缺失的翻译在构建时报错。附带路由 / SEO 辅助工具、可视化编辑器 / CMS 以及 AI 辅助翻译。
在弹窗中打开表格以清晰地查看所有数据
徽章会自动更新。快照会随时间变化。
功能逐项对比
在弹窗中打开表格以清晰地查看所有数据
| 功能 | vue-intlayer (Intlayer) | vue-i18n |
|---|---|---|
| 翻译靠近组件 | ✅ 是,.content.ts 与每个组件放在一起 | ✅ 通过 SFC <i18n> 块(可选);全局目录是常见的配置 |
| TypeScript 集成 | ✅ 从内容自动生成严格类型 | ✅ 类型良好;严格的键安全需要为 schema 定义类型并保持纪律 |
| 缺失翻译检测 | ✅ TypeScript 错误 + 构建时错误/警告 | ⚠️ 运行时回退 + 控制台警告 |
| 富内容(组件 / Markdown) | ✅ 直接支持 | ⚠️ <i18n-t> 组件插值;Markdown 需外部插件 |
| ICU 支持 | ⚠️ 进行中 | ✅ 是 |
| 格式化(日期、数字、货币) | ✅ 基于 Intl 的格式化器 | ✅ d() / n() 配合 datetimeFormats / numberFormats |
| 本地化路由 | ✅ Vue Router / Nuxt 辅助工具,getMultilingualUrls | ⚠️ 非核心(@nuxtjs/i18n 或自定义路由配置) |
| SEO 辅助工具(hreflang、sitemap、robots) | ✅ 内置辅助工具 | ❌ 非核心 |
| Tree-shaking(只交付使用的内容) | ✅ 按组件、按语言,由编译器自动完成 | ⚠️ 手动:拆分目录,按路由调用 setLocaleMessage() |
| 懒加载 | ✅ importMode: 'dynamic'(一行配置) | ✅ 手动 import() + setLocaleMessage() |
| 清除未使用的内容 | ✅ 无用字典在构建时被移除 | ❌ 未内置 |
| 测试缺失翻译(CLI / CI) | ✅ npx intlayer content test | ⚠️ 第三方(vue-i18n-extract) |
| AI 翻译 | ✅ 内置,使用你自己的提供商密钥 | ❌ 否 |
| 可视化编辑器 / CMS | ✅ 免费可视化编辑器 + 可选 CMS | ❌ 否(外部本地化平台) |
| MCP 服务器与 Agent Skills | ✅ 是 | ❌ 否 |
| 生态系统 / 社区 | ⚠️ 较小但增长迅速 | ✅ 在 Vue 生态中庞大且成熟 |
基准测试
测量了什么
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 下测量。
两个库都在 static 配置下测试,这是大多数 Vue 项目实际交付的方式:对 vue-i18n,导入每种语言的 JSON 并传给 createI18n({ messages });对 Intlayer,使用默认的 importMode: 'static'。在该模式下 Intlayer 也会打包所有语言,但编译器仍然按组件限定内容范围,所以一个页面只携带它所渲染组件的字典。
对每个构建,套件记录:
- Lib size:只导入 i18n 库的空组件的 gzip 体积。运行时的固定成本。
- Page JS:每页下载的 gzip JavaScript,对所有页面和语言取平均。
- Locale leak %:下载的 JS 中,属于用户未查看语言的翻译字符串所占比例(以
en和fr做指纹,因此 50% 意味着“另一种被测语言完整存在”;打包 10 种语言时,实际浪费更高)。 - Page leak %:下载的 JS 中,属于用户不在的页面的翻译字符串所占比例。
- Component avg:每个组件单独编译时的平均 gzip 体积。显示单个组件拖入了多少 i18n 运行时和目录。
- E2E reactivity:从选择新语言到 DOM 中
html[lang]更新之间的实际耗时(Playwright,5 次迭代)。 - Page load:
PerformanceNavigationTiming.duration。
下方数字来自 2026-09-12 的运行,使用vue-i18n11.4.0 和intlayer9.5.0 / 9.5.1。测试应用故意做得很小(每种语言几十个字符串),因此泄漏百分比描述的是一种模式:它们随你的内容增长,而运行时成本保持固定。
Vite + Vue 3 上的结果
在弹窗中打开表格以清晰地查看所有数据
| 库 | 策略 | Lib size (gz) | Lib size (min) | Page JS 平均 (gz) | Locale leak | Page leak | Component 平均 (gz) | E2E 响应速度 | Page load |
|---|---|---|---|---|---|---|---|---|---|
| base(无 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 |
基础应用的 page-leak 列留空:没有 i18n 库时,指纹识别会捕获共享 chunk 中硬编码的字符串,该数字没有意义。
如何解读
- 运行时成本。
vue-i18n是整个基准测试中最重的运行时之一:只导入它的空组件就要 24.3 KB gzip / 83.2 KB 压缩后。vue-intlayer只要 3.9 KB gzip。无论你有多少字符串,这个差距在每个页面上都要付出。 - 每页 JavaScript。 无 i18n 的应用重 41.3 KB。
vue-i18n让它增至三倍多,达到 134.9 KB;Intlayer 落在 57.1 KB,+15.8 KB,其中大部分是打包的十种语言(见下一点)。 - 泄漏。 使用
createI18n({ messages: { en, fr, ... } })时,每个页面都交付所有语言和所有页面的字符串:50% 的语言泄漏(在两种指纹语言上)和 90% 的页面泄漏。Intlayer 的static模式也打包所有语言(因此语言泄漏数字相当),但页面泄漏为 0%:一个页面只拉取它渲染的组件的字典。切换到importMode: 'dynamic'还能消除语言泄漏;该配置不在本次 Vue 运行范围内。 - 组件体积是架构差异的体现。 调用
useI18n()的组件平均编译为 196 KB,因为t()绑定到持有所有语言所有消息的全局实例。同一个组件使用useIntlayer()编译为 7.7 KB:它只触及自己的字典。 - 响应速度对两者都不是问题(2-5 ms)。一旦消息在内存中,Vue 的响应式系统让语言切换非常廉价。
@intlayer/vue-i18n,即插即用的适配器,保留了vue-i18n的 API,测得每页 47.0 KB、每组件 8.4 KB,应用代码未做改动。
作为参考,同一次运行测得 fluent-vue 每页 171.8 KB、运行时 29.7 KB、每组件 217 KB。
差距从何而来?全局实例 vs 编译后的字典
vue-i18n 是一个运行时。createI18n() 构建一个全局实例,为每种语言持有一棵消息树;useI18n() 把每个组件绑定到它;t("footer.github") 在渲染时查找键。正是这一点使 SFC <i18n> 块、v-t 和运行时消息加载成为可能,也正是因此每个组件的依赖图都包含整棵树:
复制代码到剪贴板
优化意味着你把 en.json 拆成按路由的文件,你在路由守卫中调用 setLocaleMessage(),并且你在组件移动时维护路由到文件的映射。运行时无法替你做这些,因为它不知道组件会请求哪些键。
Intlayer 把这些知识移到构建阶段。内容在组件旁声明,vite-intlayer 解析哪个组件导入哪个字典:
复制代码到剪贴板
编译器按字典、按语言精确输出该组件需要的 JSON,并丢弃没有任何导入的字典。按路由的作用域是按组件作用域的自然结果,而不是一项任务。
若还想丢弃未使用的语言,在intlayer.config.ts中设置dictionary.importMode: 'dynamic'。参见 bundle 优化文档。
开发体验
设置
vue-i18n
复制代码到剪贴板
复制代码到剪贴板
Intlayer
复制代码到剪贴板
复制代码到剪贴板
复制代码到剪贴板
组件
vue-i18n
复制代码到剪贴板
复制代码到剪贴板
在你自己为消息 schema 定义类型之前,t('counter.label') 只是一个字符串;拼写错误会直接渲染出键名。
Intlayer
复制代码到剪贴板
复制代码到剪贴板
label 和 increment 是有类型的;拼写错误是 TypeScript 错误,缺失的法语值是构建错误。
按语言懒加载
vue-i18n
复制代码到剪贴板
然后在路由守卫中调用 loadLocaleMessages(),如果想要按页面的作用域,还得自己按路由拆分 locales/{locale}.json。
Intlayer
复制代码到剪贴板
保留 vue-i18n 的 API,获得 Intlayer 的输出
@intlayer/vue-i18n 是一个即插即用的适配器:useI18n()、t()、d()、n()、{name} 和 {0} 插值、管道复数("car | cars")、v-t 和 i18n.global.locale 都继续工作,但由 vite-intlayer 编译的 Intlayer 字典提供服务。
复制代码到剪贴板
在基准测试中,同一应用的 compat 构建每页从 134.9 KB 降到 47.0 KB,每组件从 196 KB 降到 8.4 KB,组件未做改动。通过 JSON 同步插件,你现有的 locales/{locale}.json 可以继续作为事实来源。
参见 vue-i18n 迁移指南和兼容性文档。Nuxt 用户可通过 @nuxtjs/i18n 兼容性走同样的路径。
何时选择哪一个?
- 选择 vue-i18n,如果你想要标准的 Vue 方式、依赖 ICU 消息或 SFC
<i18n>块、已经在使用@nuxtjs/i18n,或者翻译平台期望集中式 JSON。如果 bundle 体积很重要,请预留时间来拆分目录并按路由懒加载。 - 选择 Intlayer,如果你想要按组件作用域的内容、严格的 TypeScript、构建时的缺失键错误、零成本的 tree-shaking 和懒加载,以及内置的编辑工具(可视化编辑器、CMS、AI 翻译、MCP 服务器)。对大型模块化 Vue / Nuxt 代码库和设计系统尤其适用。
- 选择
@intlayer/vue-i18n,如果你已经在用vue-i18n,想在不重写的情况下获得 bundle 收益。
相关对比
- next-intl vs Intlayer(同一基准测试)
- i18next vs Intlayer(同一基准测试)
- Lingui vs Intlayer(同一基准测试)
- vue-i18n vs Intlayer(功能与 DX)
- vue-i18n 过时了吗?
GitHub Star
GitHub star 是项目受欢迎程度、社区信任度和长期相关性的有力指标。虽然不是技术质量的直接衡量,但它反映了有多少开发者认为该项目有用、关注其进展并可能采用它。
结论
vue-i18n 成熟、灵活,并与 Vue 深度集成。基准测试展示了其运行时优先的设计在 Vite 构建上的代价:24 KB gzip 的运行时,一个无 i18n 时仅 41 KB 的应用每页 134.9 KB,每个页面上 90% 是其他页面的内容,以及每个都达到 196 KB 的组件,因为它们挂在全局消息树上。
Intlayer 把工作移进编译器。按组件的字典和无用内容清除是构建产物,而不是约定。在同一应用上:3.9 KB 运行时、每页 57.1 KB、0% 页面泄漏、组件小 25 倍。如果重写不在考虑之列,@intlayer/vue-i18n 可以在不改动组件的情况下走完大部分路程。
所有原始数据、测试应用和脚本都在 Benchmark Bloom 仓库中。自己跑一遍吧。
更多细节请参阅“为什么选择 Intlayer?”文档。
评论
暂无评论。成为第一个分享您想法的人吧。
