İçindekiler
Çeviri dosyalarınız sayfa yükleme sürelerinizi sessizce öldürüyor. 500+ anahtarlı tipik bir uluslararasılaştırılmış uygulama, dil başına 400-800KB çeviri paketi üretir. Bunu 15 dil ile çarpın ve 6-12MB çeviri verisi sunuyorsunuz — bunun çoğunu kullanıcılar asla görmez.
Bu rehber, bunun neden olduğunu, namespace bazlı bölmenin bunu nasıl çözdüğünü ve çeviri yüklerini %90-97 azaltan pratik implementasyon kalıplarını kapsar.
Monolitik Çeviri Dosyalarının Gizli Maliyeti
Çoğu i18n kurulumu basit başlar: locale başına tek bir translations.json dosyası. 50 anahtarda gayet iyi çalışır. Ama production uygulamalar hızla büyür:
| Ölçek | Anahtar | Dosya Boyutu (gzip) | Etki |
|---|---|---|---|
| Küçük uygulama | 50 | ~2 KB | İhmal edilebilir |
| Orta uygulama | 500 | ~18 KB | 3G'de fark edilir |
| Büyük uygulama | 2.000 | ~70 KB | Önemli |
| Kurumsal | 5.000+ | ~200 KB | Kritik darboğaz |
Sorun birden fazla dille katlanır. 15 dilde 500 anahtarlı bir uygulama, kullanıcı herhangi bir içerik görmeden önce CDN'nin 270KB çeviri verisi sunması demektir — ve yalnızca mevcut sayfa için çevirilere ihtiyaç duyarlar (tipik olarak 20-50 anahtar, ~2KB).
Gerçek dünya örneği: Better i18n'deki kendi landing sayfamız 59 namespace'te 699 anahtara ulaştı. İngilizce translations.json 478KB idi. Hintçe çeviri 841KB idi. Her ziyaretçi, yalnızca fiyatlandırma sayfasını ziyaret etse bile (14 anahtar, ~2KB gerekli) tüm dosyayı indiriyordu.
i18n Namespace'leri Nedir?
Namespace'ler, çevirilerinizdeki mantıksal gruplardır — genellikle sayfa, özellik veya alana göre düzenlenir:
{
"hero": {
"title": "Çevirileri daha hızlı gönderin",
"subtitle": "Modern uygulamalar için AI destekli lokalizasyon"
},
"pricing": {
"title": "Basit, şeffaf fiyatlandırma",
"monthly": "Aylık",
"yearly": "Yıllık"
},
"footer": {
"copyright": "© 2026 Acme Inc.",
"privacy": "Gizlilik Politikası"
}
}
i18next, react-intl ve Better i18n gibi kütüphaneler namespace'leri destekler. Tipik kullanım useTranslations("pricing") şeklindedir — SDK'ya hangi namespace'e ihtiyacınız olduğunu zaten söylüyorsunuz. SDK sadece bu bilgiyi yükleme optimizasyonu için kullanmıyor.
Çeviri Dosyalarını Bölmek İçin Üç Strateji
Strateji 1: Namespace Bazlı CDN Dosyaları
Tek monolitik dosya yerine, her namespace'i ayrı dosya olarak yayınlayın:
Önce: /en/translations.json → 478 KB (tüm 59 namespace) Sonra: /en/translations.json → 478 KB (geriye uyumlu) /en/hero.json → 1.2 KB /en/pricing.json → 2.1 KB /en/footer.json → 0.8 KB ...59 bireysel dosya
Bir sayfa hero + pricing + footer gerektirdiğinde:
- Önce: 1 istek × 478 KB = 478 KB
- Sonra: 3 istek × ~1.4 KB ort = 4.1 KB (%99 azalma)
Takas, daha fazla HTTP isteğidir. Ancak HTTP/2 multiplexing ile 3-6 küçük paralel istek, 1 büyük istekten daha hızlı tamamlanır. Ve her namespace dosyası bağımsız olarak önbelleğe alınır — pricing güncellemek hero'yu geçersiz kılmaz.
Strateji 2: Namespace Sorgu Parametresi
Tek dosyalı CDN yapısını koruyun ama sunucu tarafında filtreleme ekleyin:
GET /en/translations.json?ns=hero,pricing,footer ← Yalnızca istenen namespace'leri döndürür (~4 KB)
Avantajlar:
- Tek HTTP isteği (waterfall yok)
- R2/S3 depolama ek yükü yok (dosyalar çoğaltılmaz)
- Geriye uyumlu (
?nsparametresi yoksa = tam dosya)
Dezavantajlar:
- CDN worker mantığı gerektirir (statik dosya sunamaz)
- Cache key karmaşıklığı (her namespace kombinasyonu farklı)
- Edge'de önbelleğe almak zor (sorgu parametreleri cache hit oranını düşürür)
Strateji 3: Build-Time Code Splitting
Next.js ve Vite gibi framework'ler çevirileri build zamanında bölebilir:
// dynamic import ile next-i18next
const i18nConfig = {
ns: ['common', 'pricing'],
resourceLoader: (language, namespace) =>
import(`./locales/${language}/${namespace}.json`),
};
Bu, yalnızca her sayfanın import ettiği çevirileri paketler. Webpack/Vite namespace başına ayrı chunk'lar oluşturur.
Avantajlar:
- Sıfır runtime ek yükü (build'de çözülür)
- SSR/SSG ile çalışır (çeviriler server bundle'ına dahil)
- Tree-shaking kullanılmayan anahtarları elimine eder
Dezavantajlar:
- Yalnızca dosya tabanlı çevirilerle çalışır (CDN dağıtımı değil)
- Çevirileri güncellemek için rebuild gerektirir
- OTA (over-the-air) çeviri güncellemelerine yardımcı olmaz
Optimal Mimari: CDN + Akıllı Yükleme
En iyi yaklaşım, CDN düzeyinde namespace dosyaları ile SDK düzeyinde akıllı yüklemeyi birleştirir:
CDN yayınlar: ├── /en/translations.json ← tam paket (geriye uyumlu) ├── /en/hero.json ← namespace bazlı ├── /en/pricing.json ├── /en/footer.json └── /manifest.json ← namespace listesi + URL'ler içerir SDK davranışı: 1. manifest.json'ı getir (önbellekli, küçük) 2. Mevcut sayfanın hangi namespace'lere ihtiyacı olduğunu algıla 3. Yalnızca bu namespace dosyalarını toplu getir 4. Her namespace'i bağımsız olarak önbelleğe al 5. Navigasyonda eksik namespace'leri artımlı getir
Bu size şunları sağlar:
- Minimum başlangıç yükü — yalnızca mevcut sayfanın ihtiyaç duyduğu
- Hızlı navigasyon — paylaşılan namespace'ler (header, footer) zaten önbellekte
- Bağımsız cache invalidation — bir namespace'i güncellemek diğerlerini bozmaz
- Sıfır geliştirici ek yükü —
useTranslations("pricing")aynı şekilde çalışır - Geriye uyumluluk —
translations.jsonhala tam paketi sunar
Performans Karşılaştırmaları
Kendi landing sayfamızda namespace bölmenin etkisini ölçtük (699 anahtar, 59 namespace, 15 dil):
| Metrik | Önce (monolitik) | Sonra (namespace bölme) | İyileşme |
|---|---|---|---|
| Çeviri yükü | 478 KB | 12 KB (sayfa ort.) | %97.5 daha küçük |
| Time to First Byte | 180ms | 45ms | %75 daha hızlı |
| Toplam CDN bant genişliği/ay | 48 GB | 2.1 GB | %95.6 daha az |
| Cache hit oranı | %62 | %94 | +32 puan |
Cache hit oranı iyileşmesi granüler önbelleğe almadan gelir — pricing metnini güncellediğinizde yalnızca /en/pricing.json geçersiz kılınır. Diğer 58 namespace dosyası edge'de önbellekte kalır.
Ne Zaman Bölmemeli?
Namespace bölme her zaman doğru seçim değildir:
- Küçük uygulamalar (< 100 anahtar): Gzip'li çeviriler ~4KB'dir. Bölme, anlamlı fayda olmadan karmaşıklık ekler.
- SSG ile statik siteler: Çeviriler build zamanında paketlenip statik HTML olarak sunuluyorsa, optimize edilecek runtime yükü yoktur.
- Preloading'li tek sayfa uygulamalar: SPA'nız splash ekranı sırasında tüm çevirileri preload ediyorsa, bölme algılanan performansı iyileştirmez.
Pratik kural: Çeviri dosyanız 50KB gzip'li (kabaca 1.000+ anahtar) aşıyorsa, namespace bölme yükleme sürelerini anlamlı şekilde iyileştirecektir.
Sonuç
Büyük çeviri dosyaları çözülebilir bir performans problemidir. Mimari basittir:
- Namespace bazlı dosyalar yayınlayın — tam çeviri paketinizin yanında
- SDK'nın yalnızca gerekeni yüklemesine izin verin —
useTranslations()çağrılarına göre - Bağımsız önbelleğe alın — bir namespace güncellemesi diğerlerini geçersiz kılmasın
Bu yaklaşım, namespace'leri destekleyen herhangi bir i18n kütüphanesiyle çalışır (i18next, react-intl, Better i18n, LinguiJS). CDN düzeyindeki değişiklik evrenseldir — uygulama kodunuz aynı kalır.
500+ anahtarla 15+ dile hizmet veren uygulamalar için, bu tek değişiklik çeviri yüklerini %90-97 azaltabilir ve CDN bant genişliğini %95 kesebilir. Bu, daha iyi Core Web Vitals, daha hızlı time-to-interactive ve dünya genelinde daha mutlu kullanıcılar demektir.