エンジニアリング//7 読了時間

CDN Translation Delivery:Edge Cacheによるi18nパフォーマンス完全ガイド

Eray Gündoğmuş
共有

CDN Translation Delivery:Edge Cacheによるi18nパフォーマンス完全ガイド

翻訳の配信は、見えないところに潜むパフォーマンスの問題です。アプリのページ読み込みが1秒以下であり、画像が最適化され、バンドルがコード分割されていても、翻訳の到着が遅れると、ユーザーはレイアウトのずれ、ローディングスピナー、あるいはより深刻な問題として未翻訳のキーが画面上でちらつくのを目にすることになります。

このガイドでは、better-i18nがCloudflare R2とEdge Cachingを使って翻訳配信の問題をどのように解決するかを説明し、エンジニアリングチームが利用できるすべてのCDNオペレーションを詳しく解説します。


翻訳配信がi18nパフォーマンスに重要な理由

従来のi18nセットアップでは、翻訳をアプリケーション内にバンドルします。誤字を修正したり新しい言語を追加するたびに、完全な再ビルドと再Deployが必要になります。モバイルアプリの場合、それはApp Storeのレビューを待つことを意味します。Webアプリの場合、エンジニアリング以外の変更をブロックするDeployパイプラインを意味します。

CDN翻訳配信は、翻訳コンテンツをアプリケーションコードから切り離します。翻訳はEdgeに存在し、ユーザーに最も近いCloudflareノードから提供されます。アプリは実行時にHTTPでそれらを取得します。

パフォーマンスの特性:

  • 50ms未満の配信 — 最寄りのEdgeノードから(世界300以上の拠点)
  • オリジンへのラウンドトリップゼロ — キャッシュ済み翻訳の場合
  • インクリメンタルな更新 — アプリケーションの再Deployなし
  • 並列ローディング — 現在のページが必要とするNamespaceのみ

それを可能にするURL構造

better-i18nのすべての翻訳ファイルは、決定論的なURLパターンに従います:

https://cdn.better-i18n.com/{org}/{project}/{locale}/{namespace}.json

この構造は意図的にシンプルで予測可能です。これが意味するのは:

  1. ブラウザキャッシュがネイティブに動作します — 各ロケール・Namespaceペアは一意で安定したURLを持ちます
  2. Service Workerが既知のパスをプリキャッシュできます — ディスカバリリクエストなしに
  3. CDN Edgeノードがパスごとに独立してキャッシュしますfr/auth.jsonのキャッシュミスはen/common.jsonに影響しません
  4. あらゆるHTTPクライアントが利用できます — SDKなし、認証なし、特別なヘッダーなし

いくつかの実際の例:

# English common translations
https://cdn.better-i18n.com/acme/web-app/en/common.json

# Turkish authentication strings
https://cdn.better-i18n.com/acme/web-app/tr/auth.json

# Japanese dashboard translations
https://cdn.better-i18n.com/acme/web-app/ja/dashboard.json

各プロジェクトには/{org}/{project}/manifest.jsonにマニフェストがあり、利用可能なすべてのロケールを一覧表示します。モバイルSDKはこれを使用して、ロケールリストをハードコードせずに実行時に言語を自動検出します。


UploadとMerge:CDN更新の2つのモデル

better-i18nはCDN上の翻訳を更新するための2つの異なるアプローチを提供します。

フルUpload(cdn.uploadcdn.uploadBatch

UploadはR2上のNamespace・ロケールファイル全体を置き換えます:

# Single file
better-i18n cdn upload --locale en --namespace common

# Multiple files in one operation
better-i18n cdn upload-batch --locales en,tr,fr --namespaces common,auth

バッチUploadが適切な選択なのは:

  • 初めて新しい言語を公開するとき
  • 大規模な再構築後にCDNファイルを再構築するとき
  • TMSから完全な翻訳エクスポートをDeployするとき

バッチオペレーションは内部的に最適化されています — R2への書き込みとキャッシュの無効化がバッチ処理されるため、順次個別Uploadと比べて合計伝播時間が短縮されます。

インクリメンタルMerge(cdn.merge

MergeはR2から既存ファイルを読み取り、キーレベルの変更を適用し、結果を書き戻します:

better-i18n cdn merge --locale en --namespace common --keys "welcome,nav.home"

Mergeに含まれないキーは変更されずに残ります。インクリメンタルな更新にはより安全な選択肢です。なぜなら:

  • 偶発的な上書きなし — ファイル内の他のキーは保持されます
  • 並行安全性 — 複数のチームメンバーやCIパイプラインが異なるキーを競合なくMergeできます
  • より小さな変更範囲 — 指定されたキーのみが変更されます

Mergeプレビュー(cdn.mergePreview

Mergeを実行する前に結果をプレビューします:

better-i18n cdn merge-preview --locale en --namespace common --keys "welcome"

これは、どのキーが追加、更新、または変更なしに残るかを示すdiffを返します。データベースマイグレーションを適用前にレビューするように、CIパイプラインでMergeプレビューを使用してCDN Deployをレビューステップの後ろに置きます。


重複検出:CDNペイロードをスリムに保つ

翻訳プロジェクトが成長するにつれて、重複が蓄積します。「保存」ボタンの文字列がcommon.jsonsettings.jsonprofile.jsonの3つすべてに同一の値で存在することがあります。重複するたびにCDNのペイロードが増え、メンテナンスの手間が生じます — 1つを更新して他を忘れてしまいます。

重複の検出(cdn.detectDuplicates

better-i18n cdn detect-duplicates

これはプロジェクト内のすべてのCDNファイルをスキャンし、Namespace間で同一の翻訳値を共有するキーのレポートを生成します。レポートには以下が示されます:

  • どのキーが重複しているか
  • どのNamespaceにそれらが含まれているか
  • 共有されている値

クリーンアップ(cdn.cleanupDuplicates

better-i18n cdn cleanup-duplicates --target-namespace common

これは重複をターゲットNamespace(通常common)に統合し、ソースNamespaceから削除します。オペレーションは内部でMergeを使用するため、並行アクセスに安全です。

ベストプラクティス: 大規模な翻訳インポートやNamespaceの再編成後にcdn.detectDuplicatesを実行します。CDNペイロードを最小限に保つために定期的なクリーンアップをスケジュールしてください。


CDNライフサイクル管理

Setup(cdn.setup

プロジェクトのCDN配信を初期化します:

better-i18n cdn setup

これはR2バケット構造を作成し、Cloudflare Worker EdgeルーティングをConfigし、キャッシュルールを設定します。プロジェクトでCDN配信を初めて有効にする際に一度実行します。

ファイル管理

CDNの状態を監査するためにすべてのDeployされたファイルをリスト表示します:

better-i18n cdn list-files

各ファイルのロケール、Namespace、サイズ、最終更新タイムスタンプを返します。Deployの確認や古いファイルの特定に役立ちます。

Namespaceを廃止したりロケールを削除する際に個別ファイルを削除します:

better-i18n cdn delete-file --locale en --namespace legacy-feature

Teardown(cdn.uninstall

CDN配信を完全に削除します:

better-i18n cdn uninstall

R2ストレージ、Edge設定、キャッシュルールをクリーンアップします。プロジェクトを移行したりアプリケーションを廃止する際に使用します。


実際のパフォーマンス

本番環境でのCDN翻訳配信の姿:

メトリクス
Edgeロケーション300以上(Cloudflareネットワーク)
キャッシュヒット遅延50ms未満(典型値)
キャッシュミス遅延200ms未満(R2オリジンフェッチ)
伝播時間公開後10秒未満
Egressコスト0円(Cloudflare R2)

ゼロEgressコストの側面は強調する価値があります。従来のCDNセットアップはGB単位で帯域幅を課金します。R2では、翻訳配信のコストはトラフィック量に関係なく固定です。月に1,000万回の翻訳フェッチを提供するプロジェクトも、1,000回のプロジェクトも同じ料金を支払います。

翻訳のNamespaceベースのコード分割

Namespaceモデルは翻訳のコード分割として機能します。すべての翻訳を事前にロードする代わりに:

❌ /en/all-translations.json (450 KB)

アプリは現在のルートが必要とするものだけをロードします:

✅ /en/common.json (12 KB) + /en/auth.json (4 KB) = 16 KB

これにより、大規模な翻訳セットを持つアプリの初期ページロードが90%以上削減されます。Edge Cachingと組み合わせると、次のページナビゲーションは新しいNamespaceのみをフェッチします — dashboard.jsonはユーザーがダッシュボードに移動したときにロードされ、それより前にはロードされません。


統合アプローチ

SDK統合(推奨)

公式SDKはCDNフェッチ、キャッシュ、フォールバックを自動的に処理します:

  • @better-i18n/next — ISR/SSGサポートを備えたサーバーサイドフェッチ
  • @better-i18n/use-intl — TanStack RouterとViteアプリ向けクライアントサイドフェッチ
  • @better-i18n/expo — MMKV/AsyncStorageキャッシュを使ったオフラインファースト

各SDKはi18n.config.tsのプロジェクト識別子からCDN URLを解決します。手動でURLを構築する必要はありません。

直接HTTP(あらゆるプラットフォーム)

CDNはシンプルなHTTPSエンドポイントです。認証なし、特別なヘッダーなし:

curl https://cdn.better-i18n.com/acme/web-app/en/common.json

これにより、better-i18nの翻訳はあらゆるプラットフォームから利用可能になります:iOS(Swift)、Android(Kotlin)、バックエンドサービス(Go、Python、Ruby)、ゲームエンジン、IoTデバイス — HTTP GETリクエストを送信できるものなら何でも。


Publish-to-CDNパイプライン

翻訳を編集してから世界中に配信するまでの完全なワークフロー:

  1. 編集 — ダッシュボード、REST API、またはMCPツール
  2. 保留中の変更をプレビューgetPendingChangesでDeployされる内容を確認
  3. MergeResultをプレビューcdn.mergePreviewでキーレベルのdiffを表示(オプション)
  4. 公開publishTranslationscdn_upload同期ジョブをトリガーします
  5. モニタリングgetSyncs / getSyncでDeployステータスを追跡
  6. 確認cdn.listFilesで更新されたファイルがライブであることを確認

これにより、エンジニアリングチームはコードDeployと同じ厳密さを翻訳Deployに対しても持てます:プレビュー、公開、モニタリング、確認。


はじめに

  1. プロジェクトを作成dash.better-i18n.com
  2. cdn.setupを実行 — R2ストレージとEdgeルーティングを初期化するために
  3. 翻訳を追加してCDNに公開します
  4. 統合 — フレームワークSDKまたは直接HTTPで
  5. モニタリングcdn.listFilescdn.detectDuplicates

CDN配信は無料プランを含むすべてのプランで利用できます。翻訳は初日からEdgeでキャッシュされます。

Comments

Loading comments...