このページとあなたの好きなAIアシスタントを使ってドキュメントを要約します
このページのコンテンツはAIを使用して翻訳されました。
英語の元のコンテンツの最新バージョンを見るこのドキュメントを改善するアイデアがある場合は、GitHubでプルリクエストを送信することで自由に貢献してください。
ドキュメントへのGitHubリンクドキュメントのMarkdownをクリップボードにコピー
i18next VS Intlayer | React & Next.js 国際化 (i18n) ベンチマーク比較
i18nextは、JavaScriptエコシステムで最も広く利用されているi18nフレームワークです。react-i18nextやnext-i18nextを通じて、数多くのReactおよびNext.jsアプリケーションで採用されています。Intlayerは、コンパイラ駆動型でコンポーネントスコープ設計を採用した新しい選択肢です。
本記事では、機能リストの単なる比較ではなく、客観的な実測値に基づいて両者を比較します。掲載されている数値は、同一アプリケーションを各ライブラリでビルドし、ブラウザが実際にダウンロードするリソースを記録するオープンソーススイートBenchmark Bloomの測定結果に基づいています。
tl;dr:i18nextはベンチマーク内で最も重量級のランタイムであり、標準構成のNext.jsで1ページあたり+77 KB gzip、名前空間と遅延ロードを完全に最適化した場合でも+22 KBの増加をもたらします。対してIntlayerの増加はわずか+0.3 KBです。完全スコープ化された構成を除くすべてのi18next構成では、別ページの翻訳文字列が約90%リークして送信されますが、Intlayerはデフォルトで0%です。遅延読み込みバックエンドを使用したロケール切り替えは、react-i18nextで123〜185 msかかったのに対し、Intlayerは3〜4 msで完了しました。i18nextのAPIを維持できる互換アダプター@intlayer/next-i18nextを使用した場合でも、1ページあたり150.7 KBとなり、本家の218.5 KBから大幅に削減されます。
要約
- i18next / react-i18next / next-i18next - 実績豊富でプラグインが充実し、フレームワークに依存しません。名前空間、言語検出、各種バックエンド、プラグイン経由のICU、リッチコンテンツ用の
<Trans>をサポート。翻訳はlocales/{lng}/{ns}.jsonに一括管理されます。強力ですが、最適化(名前空間の分割、ページごとの読み込み制御、型安全性)のすべてを開発者自身で設計・保守する必要があります。 - Intlayer - コンポーネント中心のコンテンツモデル。
.content.ts辞書ファイルを対応するコンポーネントと同階層に配置。ビルド時コンパイラがコンポーネントおよびロケール単位でツリーシェイキングと遅延読み込みを実施し、コンテンツから厳格なTypeScript型を自動生成。翻訳漏れはビルド時に検出・遮断されます。ミドルウェア、SEOヘルパー、ビジュアルエディタ / CMS、AI翻訳支援も標準提供。
テーブルをモーダルで開き、すべてのデータを明確に表示
バッジは自動更新されます。測定時期により変動します。
機能比較一覧
テーブルをモーダルで開き、すべてのデータを明確に表示
| 機能 | Intlayer (react-intlayer / next-intlayer) | i18next (react-i18next / next-i18next) |
|---|---|---|
| コンポーネント同階層での翻訳定義 | ✅ 可能(各コンポーネントと同階層に.content.ts) | ❌ 不可(locales/{lng}/{ns}.jsonに集中管理) |
| TypeScript統合 | ✅ コンテンツから厳密な型を自動生成 | ⚠️ 基礎的(CustomTypeOptions拡張とリソース型定義が必要) |
| 翻訳漏れの検知 | ✅ TypeScriptエラー + ビルド時の警告・エラー | ⚠️ ランタイム時のフォールバック(saveMissing、キー表示) |
| リッチコンテンツ(JSX / Markdown) | ✅ ネイティブ対応 | ⚠️ インデックス付きプレースホルダーによる<Trans> |
| ICUメッセージ形式 | ⚠️ 開発中 | ⚠️ プラグイン経由(i18next-icu) |
| 複数形処理 | ✅ 列挙ベースのパターン | ✅ _one / _other 接尾辞(Intl.PluralRules) |
| フォーマット(日付、数値、通貨) | ✅ useNumber、useDate 等(内部でIntl利用) | ⚠️ 補間フォーマッターまたは手動のIntl.*呼び出し |
| ローカライズされたルーティングとミドルウェア | ✅ 組み込みプロキシ / ミドルウェア、getMultilingualUrls | ⚠️ 標準外(独自実装またはサードパーティ製ミドルウェアが必要) |
| SEOヘルパー(hreflang、サイトマップ等) | ✅ 標準提供 | ❌ 手動実装 |
| 同期サーバーコンポーネント | ✅ next-intlayer/serverのuseIntlayerを任意のServer Componentで直接利用可能 | ⚠️ ページでgetFixedTを呼び出し、Propsでtをバケツリレー |
| ツリーシェイキング(使用コンテンツのみ配信) | ✅ コンポーネントおよびロケール単位でコンパイラが自動処理 | ⚠️ 手動(名前空間分割 + ページごとのnsリスト + バックエンド) |
| 遅延ロード(Lazy Loading) | ✅ importMode: 'dynamic'(設定ファイルに1行追記) | ✅ バックエンドプラグイン経由(i18next-resources-to-backend等) |
| 未使用コンテンツのパージ | ✅ 参照されていない辞書はビルド時に破棄 | ❌ 標準機能なし |
| 翻訳漏れテスト(CLI / CI) | ✅ npx intlayer content test | ⚠️ i18next-parserなどのサードパーティツール |
| AI翻訳機能 | ✅ 標準搭載(独自のAPIキーを使用) | ❌ なし(Locize等の外部有償サービスを利用) |
| ビジュアルエディタ / CMS | ✅ 無料のビジュアルエディタ + 任意利用可能なCMS | ❌ なし(Locize等の外部プラットフォーム) |
| MCPサーバー & Agent Skills | ✅ 対応 | ❌ 非対応 |
| エコシステム / コミュニティ規模 | ⚠️ 比較的新しいが急速に拡大中 | ✅ 最も大規模で成熟 |
ベンチマーク測定
測定対象と環境
Benchmark Bloomスイートは、各ライブラリを用いて同一仕様のアプリケーションを構築します。10ページ(home, about, blog, careers, contact, FAQ, pricing, products, settings, team)、10ロケール(en, fr, es, de, it, pt, zh, ja, ko, ru)、同一コンポーネント・同一コンテンツで検証し、測定はenおよびfrで行われます。
各ライブラリは、基本的な構成から最適な構成まで最大4つの読み込み戦略でテストされています:
テーブルをモーダルで開き、すべてのデータを明確に表示
| 戦略 | 概要 | 想定ケース |
|---|---|---|
| static | 全言語・全ページの翻訳を初期バンドルに内包(init()にresourcesを直接指定) | プロトタイプ開発、AI生成コード |
| dynamic | バックエンド経由でアクティブ言語のみを読み込むが、全名前空間を一括ロード | 一般的な多くのプロジェクト |
| scoped-static | ルートごとに名前空間を分割するが、すべてビルド時にバンドル | 稀なケース |
| scoped-dynamic | ルートごとの名前空間分割 + バックエンド遅延ロード。現在のページ・現在の言語のみを読み込む | 厳格なパフォーマンス予算を持つ大規模アプリ |
Intlayerには「scoped」バリアントが存在しません。コンパイラが自動的にコンポーネント単位でコンテンツをスコープ化するため、staticおよびdynamicの行がすでに最適化された状態となります。
各ビルドで測定される指標:
- Lib size: i18nライブラリのみをインポートした空コンポーネントのgzipサイズ。ランタイムの固定コスト。
- Page JS: 1ページあたりにダウンロードされるJavaScriptのgzipサイズ(全ページ・全言語の平均)。
- Locale leak %: ダウンロードされたJS内の翻訳文字列のうち、ユーザーが閲覧していない言語の割合。
- Page leak %: ダウンロードされたJS内の翻訳文字列のうち、ユーザーが開いていないページの割合。
- Component avg: 独立してコンパイルされた各コンポーネントの平均gzipサイズ。
- E2E reactivity: 言語切り替え操作からDOMの
html[lang]が更新されるまでの実測時間(Playwright、5回試行の平均)。 - Hydration: Reactのハイドレーションフェーズの所要時間。
以下の測定値は、next-i18next16.3.0、react-i18next17.0.13、intlayer9.5.1を使用した2026-09-12時点のデータです。テストアプリは意図的に軽量(言語あたり数十個の文字列)に作られているため、リーク率は構造的な傾向を表しています。コンテンツ量が増加するにつれてリーク量は拡大しますが、ランタイムコストは固定されます。
Next.jsでの結果 (next-i18next)
テーブルをモーダルで開き、すべてのデータを明確に表示
| ライブラリ | 戦略 | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E応答性 | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (i18nなし) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-i18next | static | 19.7 KB | 218.5 KB | 0.0% | 89.8% | 78.5 KB | 16.4 ms | 15.6 ms |
next-i18next | dynamic | 19.7 KB | 169.5 KB | 50.0% | 89.8% | 26.1 KB | 15.4 ms | 27.7 ms |
next-i18next | scoped-static | 19.7 KB | 220.1 KB | 0.0% | 89.8% | 78.9 KB | 16.4 ms | 14.7 ms |
next-i18next | scoped-dynamic | 19.7 KB | 163.4 KB | 0.0% | 0.0% | 27.1 KB | 15.9 ms | 15.1 ms |
next-intlayer | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
@intlayer/next-i18next (互換) | static | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 10.7 ms | 11.3 ms |
@intlayer/next-i18next (互換) | dynamic | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 11.9 ms | 10.6 ms |
結果の解説
- ランタイムコスト:
i18nextコア +react-i18nextは、空のコンポーネントでも19.7 KB gzipと測定対象中最大で、next-intlayerの5.5 KBを大きく上回ります。 - 標準構成の肥大化:
init()にresourcesをインライン化すると、ベースアプリから+77.5 KB増の218.5 KB/ページに達します。全ページが全名前空間を持ち歩くためです。 - 最適化の難易度: バックエンド(
dynamic)に切り替えると49 KB削減できますが、依然として別ページの文字列が90%リークし、測定構成では半分が別言語の文字列となります。ルート単位の名前空間分割(scoped-dynamic)を導入してようやくリーク0%(163.4 KB)に達しますが、設定不要なIntlayerの141.3 KBより22.4 KB重い結果となります。 - コンポーネントサイズ:
useTranslation()を使用するコンポーネントは構成に応じて26〜79 KBに膨らみますが、useIntlayer()を使う同一コンポーネントは6.9 KBで済みます。 - ハイドレーション:
dynamic構成では27.7 msに悪化します。クライアント側でReactがハイドレーションを開始する前に、i18nextインスタンスが初期化されバックエンドを解決する必要があるためです。
TanStack Startでの結果 (react-i18next)
Next.js特有のオーバーヘッドを排除するため、TanStack Start上で純粋なreact-i18nextを使用した比較です。
テーブルをモーダルで開き、すべてのデータを明確に表示
| ライブラリ | 戦略 | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E応答性 | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (i18nなし) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms | 21.6 ms |
react-i18next | static | 18.4 KB | 180.3 KB | 50.0% | 89.8% | 24.3 KB | 12.9 ms | 85.1 ms |
react-i18next | dynamic | 18.4 KB | 136.4 KB | 23.1% | 89.8% | 24.8 KB | 123.1 ms | 32.9 ms |
react-i18next | scoped-static | 18.4 KB | 184.2 KB | 50.7% | 89.8% | 25.3 KB | 185.1 ms | 25.2 ms |
react-i18next | scoped-dynamic | 18.4 KB | 127.2 KB | 0.0% | 0.0% | 26.7 KB | 17.6 ms | 11.3 ms |
intlayer | static | 5.0 KB | 125.8 KB | 50.0% | 0.0% | 8.1 KB | 3.2 ms | 11.5 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms | 14.1 ms |
結果の解説
- 初期の
react-i18nextアプリはベースアプリより+69 KB/ページ重く、ハイドレーションに85 ms(ベースの4倍)かかります。初回の描画前にすべてのリソースツリーを解析・登録するためです。 - 言語切り替え時の遅延: バックエンドによる遅延読み込みを行う場合、言語を変更するとネットワーク往復が発生してから
html[lang]が更新されるため、dynamicで123 ms、scoped-staticで185 msを要します。対してIntlayerはどちらのモードでも3〜4 msで即座にDOMが反映されます。 - 最大限に最適化した
scoped-dynamicでも127.2 KBと、Intlayerのdynamicより+8.6 KB重く、ルートと名前空間のマッピングやSuspenseの設定などの複雑な作業が必要です。 - Intlayerの
staticは、該当ページのコンポーネントがインポートした辞書のみをバンドルするため、初期状態でページリーク0%です。importMode: 'dynamic'を設定すれば、言語リークも0%になります。 - コンポーネントサイズ:
react-i18nextの24〜27 KBに対し、Intlayerは6〜8 KBです。
なぜこれほどの差が出るのか? グローバルインスタンス vs コンパイル済み辞書
i18nextは2012年にランタイム主導で設計されました。グローバルインスタンスがリソースストアを保持し、プラグインがそれを拡張し、描画時にt()がキーを検索します。この構造が高い汎用性をもたらす一方で、オーバーヘッドの原因となっています:
コードをクリップボードにコピー
インスタンスはコンポーネントがどのキーを必要とするか事前に知ることができないため、指定された名前空間をすべて保持します。最適化のためには、開発者自身がカタログを名前空間に分割し、ページごとの依存関係を定義し、コンポーネントの移動に合わせてメンテナンスし続ける必要があります。ベンチマークノートにある通り、「型安全性を保ちながら各ページに必要な名前空間を正確に把握・維持することは非常に過酷な作業」です。
Intlayerはグローバルインスタンスを排除します。コンテンツはコンポーネントのすぐ隣で宣言され、コンパイラがビルド時に依存関係グラフを解決します:
コードをクリップボードにコピー
@intlayer/swc / @intlayer/babelがコンポーネントと辞書の依存関係を追跡し、アクティブな言語に必要な辞書のみをバンドルし、未使用のコンテンツを切り捨てます。「scoped-dynamic」な最適化は、手作業のルールではなくビルドの成果物として自動的に実現されます。
dynamic行の数値を再現するには、intlayer.config.tsでdictionary.importMode: 'dynamic'を設定します。詳細はバンドル最適化ドキュメントを参照してください。
開発者体験(DX)
セットアップの比較
next-i18next (App Router)
コードをクリップボードにコピー
これに加えて、クライアント側のI18nProviderの作成、generateStaticParamsの設定、各ページでの名前空間リストの指定が必要です。
Intlayer
コードをクリップボードにコピー
コードをクリップボードにコピー
クライアントコンポーネント
react-i18next
コードをクリップボードにコピー
コードをクリップボードにコピー
このコンポーネントを描画するページはabout名前空間をロードする必要があり、CustomTypeOptionsを拡張しない限りt("counter.label")の型安全性は保証されません。
Intlayer
コードをクリップボードにコピー
コードをクリップボードにコピー
labelとincrementは厳格に型付けされており、キーのタイポはTypeScriptエラーになり、フランス語の翻訳欠落はビルド時にエラーとして検出されます。
同期サーバーコンポーネント
next-i18next
コードをクリップボードにコピー
ページ側でi18n.getFixedT(locale, "about")を呼び出し、Propsを通じてtとlocaleを渡す必要があります。
Intlayer
コードをクリップボードにコピー
i18nextのAPIのままIntlayerの最適化を享受する
既存のコンポーネントを書き換えることなく、上記のベンチマーク性能を得ることも可能です。@intlayer/i18next、@intlayer/react-i18next、@intlayer/next-i18nextはドロップイン互換アダプターとして機能します。useTranslation、t()、<Trans>、{{interpolation}}、複数形接尾辞、コンテキスト接尾辞、returnObjectsがそのまま動作し、背後ではIntlayerコンパイラが辞書を最適化して供給します。
コードをクリップボードにコピー
コードをクリップボードにコピー
ベンチマークでは、アプリコードを変更することなく、Next.jsアプリが1ページあたり218.5 KBから150.7 KBへ、コンポーネントが78.5 KBから9.7 KBへ、ページリークが~90%から0%へと改善し、ハイドレーション時間も15.6 msから11.3 msへ短縮されました。既存のlocales/{lng}/{ns}.jsonは、JSON同期プラグインを介してマスターデータのまま運用できます。
詳細は移行ガイドをご覧ください: i18next, react-i18next, next-i18next。
どちらを選ぶべきか?
- i18nextを選ぶべき場合: 豊富なプラグインエコシステム(各種バックエンド、ICU、Locize等)が不可欠な場合、React以外の領域(Node.jsサービス、Vanilla JS、他フレームワーク)でも同一ツールを使いたい場合、チームがすでに習熟している場合、翻訳プラットフォームが
locales/{lng}/{ns}.jsonを前提としている場合。ただし、パフォーマンスを追求する場合は名前空間の設計やページマッピングの維持に十分なリソースを確保してください。 - Intlayerを選ぶべき場合: コンポーネントスコープのコンテンツ管理、厳格なTypeScript型付け、ビルド時の翻訳漏れ検出、自動ツリーシェイキングと遅延ロード、瞬時のロケール切り替え、同期サーバーコンポーネント、統合編集ツール(ビジュアルエディタ、CMS、AI翻訳支援、MCPサーバー)を重視する場合。モジュール化されたコードベースやデザインシステムに最適です。
@intlayer/*-i18nextアダプターを選ぶべき場合: すでにi18nextを採用しており、大規模なコード書き換えなしにバンドルサイズと応答性の向上を図りたい場合。
関連する比較記事
- next-intl vs Intlayer(同一ベンチマーク)
- Lingui vs Intlayer(同一ベンチマーク)
- vue-i18n vs Intlayer ベンチマーク(同一ベンチマーク)
- next-i18next vs next-intl vs Intlayer
- react-i18next vs react-intl vs Intlayer
- i18nextは時代遅れか?
GitHubスター
GitHubスターは、プロジェクトの認知度、コミュニティの信頼、長期的な継続性の目安となります。技術的な優劣を直接測るものではありませんが、どれだけの開発者が関心を持ち、実務で採用しているかを反映しています。
結論
i18nextは10年以上にわたるメンテナンスと抜群の汎用性により、現在の地位を確立しました。しかし、今回のベンチマークはそのランタイム依存型アーキテクチャのコストを浮き彫りにしています。一般的な構成では1ページあたり+70〜77 KB gzipが加算され、別ページの文字列が約90%漏洩し、遅延ロード時の言語切り替えに100 ms以上かかります。リークを0%に抑えることも可能ですが、それには手動での名前空間マッピングが必要であり、それでもなおIntlayerより9〜22 KB重くなります。
Intlayerはこの負担をコンパイラに移行させました。コンポーネント単位の辞書分割、ロケールごとの遅延ロード、未使用コンテンツのパージは、手作業のルールではなくビルドの成果物として自動化されます。同一アプリでの実測値は、1ページあたり+0.3 KB、リーク0%、コンポーネントサイズ3〜10倍削減、ロケール切り替え3〜4 msです。
テストアプリ、生データ、自動化スクリプトはすべてBenchmark Bloomリポジトリで公開されています。ぜひご自身で追試してみてください。
詳細は'Why Intlayer?' ドキュメントをご覧ください。
コメント
まだコメントはありません。最初のコメントを共有しましょう。
