首页演练场案例展示应用文档博客
    • English英语
      EN
    • русский俄语
      RU
    • 日本語日语
      JA
    • français法语
      FR
    • 한국어韩语
      KO
    • 中文中文
      ZH
    • español西班牙语
      ES
    • Deutsch德语
      DE
    • العربية阿拉伯语
      AR
    • italiano意大利语
      IT
    • British English英国英语
      EN-GB
    • português葡萄牙语
      PT
    • हिन्दी印地语
      HI
    • Türkçe土耳其语
      TR
    • polski波兰语
      PL
    • Indonesia印度尼西亚语
      ID
    • Tiếng Việt越南语
      VI
    • українська乌克兰语
      UK
    /
    按框架筛选文档
    Alt+←
    为什么Intlayer?
    开始
    概念
    • Intlayer如何工作
    • 配置
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • 可视化编辑器
    • CMS
    • CI/CD集成
    • 翻译复数枚举条件性别插入文件嵌套MarkdownHTML函数获取
    • 每个语言环境的文件
    • 编译器
    • 自动填充
    • 测试
    • 打包优化
    环境
    • Next.js 14和应用路由器
      Next.js 15
      Next.js 无 locale URL
      Next.js和页面路由器
      编译器
    • Tanstack Start Solid
    • Astro和React
      Astro和Svelte
      Astro和Vue
      Astro和Solid
      Astro和Preact
      Astro和Lit
      Astro和Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt和Vue
    • Vite和Solid
    • SvelteKit
    • Vite和Preact
    • Vite和Vanilla JS
    • Vite和Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native和Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx和React
    Plugins
    • JSON
    • gettext (.po)
    VS Code扩展
    代理
    • MCP服务器
    • 代理技能
    发布
    • v8
    • v7
    • v6
    基准测试
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    博客
    问问题
    1. Documentation
    2. 基准测试
    3. TanStack
    作者: Aymeric PINEAU
    Creation:2026-04-20Last update:2026-05-18
    在 GitHub 上查看应用程序模板

    此页面有可用的应用程序模板。

    将此文档参考到您的 AI 助手
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商

    版本历史

    1. "添加 GitHub 明星对比"
      v8.9.82026/5/18
    2. "初始化基准测试"
      v8.7.52026/1/6

    此页面的内容已使用 AI 翻译。

    查看英文原文的最新版本
    编辑此文档

    如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。

    文档的 GitHub 链接
    Copy

    复制文档 Markdown 到剪贴板

    TanStack Start i18n 库 - 2026 年基准测试报告

    本页面是关于 TanStack Start i18n 解决方案的基准测试报告。

    目录

    交互式基准测试

    结果参考:

    intlayer.org
    查看完整的基准测试数据

    查看完整的基准测试仓库点击这里。

    简介

    国际化解决方案是 React 应用中最重型的依赖之一。在 TanStack Start 上,主要风险在于发送了不必要的内容:同个路由的打包包中包含了其他页面和其他语言环境的翻译。

    随着应用规模的增长,这个问题会使发送到客户端的 JavaScript 体积迅速膨胀,并拖慢导航速度。

    实际上,在优化程度最低的实现中,国际化后的页面体积可能比无 i18n 的版本重数倍。

    另一个影响是开发体验(DX):内容声明方式、类型、命名空间组织、动态加载以及语言环境更改时的响应性。

    TL;DR

    • Intlayer: 为 TanStack Start 提供最佳性能和最小的打包体积 (v8.7.12)。
    • react-i18next & use-intl: 拥有庞大生态系统的成熟替代方案,但体积显著更大且优化更为复杂。
    • Paraglide: 创新的 Tree-shaking 理念,但在实际应用中并未生效。在 TanStack Start 中 DX 复杂且存在响应性开销。
    • 应当避免: General Translation (GT) 和 Lingo.dev。由于严重的性能问题、AI 配额限制以及供应商锁定 (vendor lock-in)。

    测试你的应用

    为了快速发现 i18n 泄漏问题,我建立了一个免费扫描器,你可以在这里试用。

    intlayer.org

    问题所在

    要限制多语言应用的成本,有两个关键手段:

    • 按页面/命名空间拆分内容,这样在不需要时就不会加载整个字典
    • 仅在需要时动态加载正确的语言环境

    理解这些方法的技术限制:

    动态加载

    如果没有动态加载,大多数解决方案会从第一次渲染开始就将消息保留在内存中,这对于路由和语言环境较多的应用来说会产生巨大的开销。

    采用动态加载意味着需要权衡:初始 JS 减少了,但有时切换语言时会多出一次请求。

    内容拆分

    围绕 const t = useTranslation() + t('a.b.c') 构建的语法非常方便,但往往鼓励在运行时保留大型 JSON 对象。除非库提供了真正的按页拆分策略,否则这种模型很难进行 Tree-shaking。

    方法论

    在此基准测试中,我们对比了以下库:

    • Base App(无 i18n 库)
    • react-intlayer (v8.7.12)
    • react-i18next (v17.0.2)
    • use-intl (v4.9.1)
    • @lingui/core (v5.3.0)
    • @inlang/paraglide-js (v2.15.1)
    • @tolgee/react (v7.0.0)
    • react-intl (v10.1.1)
    • wuchale (v0.22.11)
    • gt-react (vlatest)
    • lingo.dev (v0.133.9)

    框架使用 TanStack Start,构建了一个拥有 10 个页面和 10 种语言的多语言应用。

    我们对比了四种加载策略:

    显示表格的所有内容

    在弹窗中打开表格以清晰地查看所有数据

    策略 无命名空间(全局) 有命名空间(局部/作用域)
    静态加载 Static: 启动时全部加载到内存。 Scoped static: 按命名空间拆分;启动时全部加载。
    动态加载 Dynamic: 按语言环境按需加载。 Scoped dynamic: 按命名空间和语言环境进行更细粒度的加载。

    策略总结

    • Static (静态): 简单;初始加载后无网络延迟。缺点:打包体积大。
    • Dynamic (动态): 减轻初始重量(懒加载)。适用于语言环境较多的情况。
    • Scoped static (局部静态): 保持代码组织良(逻辑分离),且无需复杂的额外网络请求。
    • Scoped dynamic (局部动态): 代码分割和性能的最佳方案。通过仅加载当前视图和活动语言环境所需的内容来最小化内存占用。

    GitHub 星数

    GitHub 星数是项目受欢迎程度、社区信任和长期相关性的有力指标。虽然星数不是技术质量的直接衡量标准,但它们反映了有多少开发人员发现该项目有用、关注其进展并可能采用它。在评估项目价值时,星数有助于比较不同方案的吸引力,并提供对生态系统增长的见解。

    Star History Chart

    结果详情

    1 - 应当避免的解决方案

    应当明确避开诸如 gt-react 或 lingo.dev 之类的解决方案。它们结合了供应商锁定和代码库污染。更糟的是:尽管投入了大量时间尝试实施,但我从未让它们在 TanStack Start 上正常工作(类似于 Next.js 下的 gt-next)。

    遇到的问题:

    (General Translation) (gt-react@latest):

    • 对于一个约 110kb 的应用,gt-react 额外增加了超过 440kb(参考同个基准测试中 Next.js 实现的量级)。
    • 第一次使用 General Translation 构建就提示 Quota Exceeded, please upgrade your plan。
    • 翻译未渲染;我收到了错误 Error: <T> used on the client-side outside of <GTProvider>,这似乎是库的一个 Bug。
    • 在实施 gt-tanstack-start-react 时,我还遇到了该库的一个问题:does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser,这导致应用崩溃。在报告此问题后,维护者在 24 小时内修复了它。
    • 这些库通过 initializeGT() 函数使用了一种反模式,阻碍了打包包进行干净的 Tree-shaking。

    (Lingo.dev) ([email protected]):

    • AI 配额超出(或服务端依赖受阻),使得不付钱的情况下构建或部署极具风险。
    • 编译器丢失了近 40% 的翻译内容。我不得不将所有的 .map 重写为扁平的组件块才使其工作。
    • 它们的 CLI 存在 Bug,会无故重置配置文件。
    • 构建时,当有新内容添加时,它会完全抹除生成的 JSON 文件。结果是几个键的改动就可能抹去数百个现有键。
    • 我曾在 TanStack Start 上遇到该库的响应性问题:切换语言环境时,我必须强制重新渲染 Provider 才能使其生效。

    2 - 实验性解决方案

    (Wuchale) ([email protected]):

    Wuchale 背后的想法很有趣,但尚非可行方案。我遇到了该库的响应性问题,不得不强制重新渲染 Provider 才能让应用在 TanStack Start 上运行。文档也相当模糊,增加了上手难度。

    3 - 可接受的解决方案

    (Paraglide) (@inlang/[email protected]):

    Paraglide 提供了一种创新且经过深思熟虑的方法。即便如此,在此基准测试中,其公司宣称的 Tree-shaking 在我的 Next.js 实现或 TanStack Start 中并未生效。工作流和 DX 也比其他选项更复杂。就个人而言,我不喜欢每次推送到代码库前都要重新生成 JS 文件,这通过 PR 产生了持续的合并冲突风险。

    关于 paraglide 的说明:该解决方案通过将代码注入到您的代码库中进行导入,因此基准测试报告中的“库体积”指标几乎为 0。代码生成是一件好事,因为所使用的函数将仅包含必要的逻辑(全部前缀 vs 无前缀、cookie vs 存储等)。相比之下,Intlayer 通过在构建中注入环境变量来进行过滤,以强制打包工具根据逻辑对内容进行 Tree-shake。得益于此,paraglide 和 intlayer 最终成为比 i18next 或 next-intl 轻 6-10 倍的解决方案。

    (Tolgee) (@tolgee/[email protected]):

    Tolgee 解决了前面提到的许多问题。我发现它比其他采用类似方法的工具更难上手。它不提供类型安全,这极大增加了在编译时捕捉缺失键的难度。我不得不使用自己的 API 封装 Tolgee 的 API 以添加缺失键检测。

    在 TanStack Start 上我也遇到了响应性问题:切换语言环境时,我必须强制 Provider 重新渲染并订阅语言环境更改事件,切换后的加载才能正常进行。

    (use-intl) ([email protected]):

    use-intl 是 React 生态中最时髦的“intl”成员(与 next-intl 同系),常被 AI Agent 推荐,但在我看来,在性能优先的环境下这是错误的。入门相对简单,但在实践中,优化和限制泄漏的过程相当复杂。同样,结合动态加载 + 命名空间 + TypeScript 类型会极大降低开发速度。

    在 TanStack Start 上你可以避开 Next.js 特有的陷阱(setRequestLocale、静态渲染),但核心问题是一样的:如果没有严格的规范,打包包很快会承载过多消息,而且维护每条路由的命名空间会变得非常痛苦。

    (react-i18next) ([email protected]):

    react-i18next 可能最受欢迎,因为它是最早满足 JavaScript 应用 i18n 需求的方案之一。它还针对特定问题拥有广泛的社区插件。

    尽管如此,它与基于 t('a.b.c') 的技术栈有着相同的重大缺点:优化是可能的,但非常耗时,且大型项目容易陷入不良实践(命名空间 + 动态加载 + 类型)。

    消息格式也不同:use-intl 使用 ICU MessageFormat,而 i18next 使用自己的格式--如果混合使用它们,会增加工具链或迁移的复杂度。

    (Lingui) (@lingui/[email protected]):

    Lingui 常受赞誉。就个人而言,我觉得围绕 lingui extract / lingui compile 的工作流比其他方案更复杂,且在此 TanStack Start 基准测试中没有明显的优势。我还注意到语法不统一,容易误导 AI(例如 t()、t''、i18n.t()、<Trans>)。

    (react-intl) ([email protected]):

    react-intl 是来自 Format.js 团队的高性能实现。但 DX 依然繁琐:const intl = useIntl() + intl.formatMessage({ id: "xx.xx" }) 增加了复杂度和额外的 JavaScript 开销,并将全局 i18n 实例绑定到了 React 树中的许多节点。

    4 - 推荐方案

    在本次 TanStack Start 基准测试中,没有与 next-translate(Next.js 插件 + getStaticProps)直接对应的方案。对于那些确实想要 t() API 且拥有成熟生态的团队,react-i18next 和 use-intl 仍是“合理”的选择,但要做好投入大量时间进行优化以避免泄漏的准备。

    (Intlayer) ([email protected]):

    出于客观性考量,我不会亲自评价 react-intlayer,因为这是我自己的解决方案。

    个人见解

    此见解纯属个人观点,不影响基准测试结果。尽管如此,在 i18n 领域,常能看到关于 const t = useTranslation('xx') + <>{t('xx.xx')}</> 模式的共识。

    在 React 应用中,我个人认为将函数作为 ReactNode 注入是一种反模式。它还会增加可避免的复杂性和 JavaScript 执行开销(即使几乎察觉不到)。

    Next.js
    Vue
    Alt+→

    在此页面

      讨论是匿名的,并会定期审查以解决常见问题。欢迎分享功能想法、对文档的反馈或任何与 Intlayer 相关的内容, 我们会利用这些意见来制定路线图并改进产品。

      动态 JSON 加载

      在运行时懒加载翻译

      有作用域的 JSON (命名空间)

      每页翻译命名空间

      I18n 性能基准测试

      暂无数据

      这个指标是什么?

      国际化库包的总 gzip 压缩大小。它仅包含 tree-shaking 和压缩(minification)后的提供者(provider)和内容检索逻辑。

      为什么这很重要?

      较小的库大小可减少初始 JavaScript 负载,从而缩短客户端的下载和执行时间。

      视图形式