Índice
CDN Translation Delivery: Guía de rendimiento i18n con Edge Cache
La entrega de traducciones es un problema de rendimiento que se oculta a simple vista. Tu app puede tener cargas de página en menos de un segundo, imágenes optimizadas y bundles con code-splitting — pero si las traducciones llegan tarde, los usuarios ven cambios de layout, spinners de carga o, peor aún, keys sin traducir parpadeando en la pantalla.
Esta guía explica cómo better-i18n resuelve la entrega de traducciones usando Cloudflare R2 y edge caching, y recorre el conjunto completo de operaciones CDN disponibles para los equipos de ingeniería.
Por qué la entrega de traducciones importa para el rendimiento i18n
Las configuraciones i18n tradicionales incluyen las traducciones dentro de la aplicación. Cada vez que corriges un error tipográfico o añades un nuevo idioma, necesitas un rebuild completo y un nuevo deploy. Para apps móviles, eso significa esperar la revisión del App Store. Para apps web, significa un pipeline de deploy que bloquea un cambio fuera del equipo de ingeniería.
CDN Translation Delivery desacopla el contenido de las traducciones del código de la aplicación. Las traducciones viven en el edge y se sirven desde el nodo Cloudflare más cercano al usuario. Tu app las obtiene en tiempo de ejecución via HTTP.
Las características de rendimiento:
- Entrega en menos de 50ms desde el nodo edge más cercano (300+ ubicaciones en todo el mundo)
- Cero round-trips al origen para traducciones cacheadas
- Actualizaciones incrementales sin necesidad de redesplegar la aplicación
- Carga paralela solo de los namespaces que la página actual necesita
La estructura de URL que lo hace posible
Cada archivo de traducción en better-i18n sigue un patrón de URL determinista:
https://cdn.better-i18n.com/{org}/{project}/{locale}/{namespace}.json
Esta estructura es intencionalmente simple y predecible. Esto significa:
- Los caches del navegador funcionan de forma nativa — cada par locale-namespace tiene una URL única y estable
- Los service workers pueden pre-cachear rutas conocidas sin peticiones de descubrimiento
- Los nodos edge del CDN cachean de forma independiente por ruta, por lo que un cache miss de
fr/auth.jsonno afecta aen/common.json - Cualquier cliente HTTP puede consumirlo — sin SDK, sin autenticación, sin headers especiales
Algunos ejemplos reales:
# 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
Cada proyecto también tiene un manifest en /{org}/{project}/manifest.json que lista todos los locales disponibles. Los SDKs móviles lo usan para descubrir automáticamente los idiomas en tiempo de ejecución sin tener que hardcodear listas de locales.
Upload vs. Merge: Dos modelos para actualizar el CDN
better-i18n ofrece dos enfoques distintos para actualizar las traducciones en el CDN.
Upload completo (cdn.upload y cdn.uploadBatch)
Upload reemplaza el archivo namespace-locale completo en R2:
# 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
El batch upload es la elección correcta cuando:
- Se publica un nuevo idioma por primera vez
- Se reconstruyen los archivos CDN tras una reestructuración importante
- Se despliega una exportación completa de traducciones desde tu TMS
Las operaciones en batch están optimizadas internamente — las escrituras en R2 y las invalidaciones de cache se agrupan, reduciendo el tiempo total de propagación comparado con uploads individuales secuenciales.
Merge incremental (cdn.merge)
Merge lee el archivo existente en R2, aplica cambios a nivel de key y escribe el resultado de vuelta:
better-i18n cdn merge --locale en --namespace common --keys "welcome,nav.home"
Los keys no incluidos en el merge permanecen sin cambios. Es la opción más segura para actualizaciones incrementales porque:
- Sin sobrescrituras accidentales — los demás keys del archivo se preservan
- Seguridad ante concurrencia — varios miembros del equipo o pipelines CI pueden mergear diferentes keys sin conflictos
- Superficie de cambio menor — solo se tocan los keys especificados
Vista previa del Merge (cdn.mergePreview)
Antes de ejecutar un merge, ver el resultado:
better-i18n cdn merge-preview --locale en --namespace common --keys "welcome"
Esto devuelve un diff que muestra qué keys se añadirían, actualizarían o quedarían sin cambios. Usa la vista previa del merge en pipelines CI para que los deploys al CDN pasen por un paso de revisión — igual que revisarías una migración de base de datos antes de aplicarla.
Detección de duplicados: Mantener el payload CDN liviano
A medida que los proyectos de traducción crecen, los duplicados se acumulan. Un texto para el botón "Guardar" puede existir en common.json, settings.json y profile.json con valores idénticos en los tres. Cada duplicado aumenta el payload total del CDN y genera sobrecarga de mantenimiento — actualizas uno, olvidas los otros.
Detectar duplicados (cdn.detectDuplicates)
better-i18n cdn detect-duplicates
Esto escanea todos los archivos CDN de tu proyecto y produce un informe de keys que comparten valores de traducción idénticos entre namespaces. El informe muestra:
- Qué keys están duplicados
- En qué namespaces se encuentran
- El valor compartido
Limpieza (cdn.cleanupDuplicates)
better-i18n cdn cleanup-duplicates --target-namespace common
Esto consolida los duplicados en un namespace objetivo (típicamente common) y los elimina de los namespaces fuente. La operación usa merge internamente, por lo que es segura para acceso concurrente.
Buena práctica: Ejecuta cdn.detectDuplicates después de cada importación grande de traducciones o reorganización de namespaces. Programa limpiezas periódicas para mantener los payloads CDN al mínimo.
Gestión del ciclo de vida del CDN
Setup (cdn.setup)
Inicializar la entrega CDN para tu proyecto:
better-i18n cdn setup
Esto crea la estructura del bucket R2, configura el edge routing del Cloudflare Worker y establece las reglas de cache. Ejecútalo una vez al habilitar la entrega CDN por primera vez para un proyecto.
Gestión de archivos
Listar todos los archivos desplegados para auditar el estado del CDN:
better-i18n cdn list-files
Devuelve el locale, namespace, tamaño y timestamp de última modificación de cada archivo. Útil para verificar despliegues e identificar archivos obsoletos.
Eliminar archivos individuales al deprecar un namespace o eliminar un locale:
better-i18n cdn delete-file --locale en --namespace legacy-feature
Teardown (cdn.uninstall)
Eliminar la entrega CDN por completo:
better-i18n cdn uninstall
Limpia el almacenamiento R2, la configuración edge y las reglas de cache. Úsalo al migrar un proyecto o dar de baja una aplicación.
Rendimiento en la práctica
Así es como se ve la entrega de traducciones CDN en producción:
| Métrica | Valor |
|---|---|
| Ubicaciones edge | 300+ (red Cloudflare) |
| Latencia con cache hit | < 50ms (típico) |
| Latencia con cache miss | < 200ms (fetch de origen R2) |
| Tiempo de propagación | < 10 segundos tras publicar |
| Costo de egress | 0 $ (Cloudflare R2) |
El aspecto del cero costo de egress merece énfasis. Las configuraciones CDN tradicionales cobran por GB de ancho de banda. Con R2, los costos de entrega de traducciones son fijos independientemente del volumen de tráfico. Un proyecto que sirve 10 millones de fetches de traducción al mes paga lo mismo que uno con 1.000.
Code splitting basado en namespace para traducciones
El modelo de namespace actúa como code splitting para traducciones. En lugar de cargar todas las traducciones por adelantado:
❌ /en/all-translations.json (450 KB)
Tu app carga solo lo que la ruta actual necesita:
✅ /en/common.json (12 KB) + /en/auth.json (4 KB) = 16 KB
Esto reduce la carga inicial de la página en más del 90% para apps con conjuntos de traducción grandes. Combinado con edge caching, las navegaciones posteriores solo obtienen el nuevo namespace — dashboard.json se carga cuando el usuario navega al dashboard, no antes.
Enfoques de integración
Integración con SDK (Recomendado)
Los SDKs oficiales gestionan automáticamente el fetching CDN, el caching y el fallback:
@better-i18n/next— Fetching server-side con soporte ISR/SSG@better-i18n/use-intl— Fetching client-side para TanStack Router y apps Vite@better-i18n/expo— Offline-first con caching MMKV/AsyncStorage
Cada SDK resuelve la URL del CDN desde el identificador de proyecto en tu i18n.config.ts. No se necesita construcción manual de URLs.
HTTP directo (Cualquier plataforma)
El CDN es un endpoint HTTPS simple. Sin autenticación, sin headers especiales:
curl https://cdn.better-i18n.com/acme/web-app/en/common.json
Esto hace que las traducciones de better-i18n sean consumibles desde cualquier plataforma: iOS (Swift), Android (Kotlin), servicios backend (Go, Python, Ruby), game engines, dispositivos IoT — cualquier cosa que pueda hacer una petición HTTP GET.
El pipeline Publish-to-CDN
El flujo completo desde editar una traducción hasta servirla globalmente:
- Editar — Dashboard, REST API o herramientas MCP
- Vista previa de cambios pendientes —
getPendingChangesmuestra lo que se desplegará - Vista previa del resultado del merge —
cdn.mergePreviewmuestra el diff a nivel de key (opcional) - Publicar —
publishTranslationslanza el job de synccdn_upload - Monitorear —
getSyncs/getSyncrastrea el estado del despliegue - Verificar —
cdn.listFilesconfirma que el archivo actualizado está en vivo
Esto da a los equipos de ingeniería el mismo rigor para los despliegues de traducciones que para los despliegues de código: previsualizar, publicar, monitorear, verificar.
Primeros pasos
- Crea tu proyecto en dash.better-i18n.com
- Ejecuta
cdn.setuppara inicializar el almacenamiento R2 y el edge routing - Añade traducciones y publícalas en el CDN
- Integra con el SDK de tu framework o usa HTTP directo
- Monitorea con
cdn.listFilesycdn.detectDuplicates
La entrega CDN está disponible en todos los planes, incluido el gratuito. Tus traducciones están cacheadas en el edge desde el primer día.