@intlayer/docs 8.9.4 → 8.9.6-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/ar/benchmark/index.md +0 -3
- package/docs/ar/benchmark/nextjs.md +15 -6
- package/docs/ar/benchmark/solid.md +155 -0
- package/docs/ar/benchmark/svelte.md +148 -0
- package/docs/ar/benchmark/tanstack.md +12 -3
- package/docs/ar/benchmark/vue.md +160 -0
- package/docs/ar/configuration.md +16 -12
- package/docs/ar/dictionary/content_file.md +51 -1
- package/docs/ar/plugins/sync-po.md +0 -21
- package/docs/bn/configuration.md +16 -12
- package/docs/cs/configuration.md +16 -12
- package/docs/de/benchmark/index.md +0 -3
- package/docs/de/benchmark/nextjs.md +15 -6
- package/docs/de/benchmark/solid.md +155 -0
- package/docs/de/benchmark/svelte.md +148 -0
- package/docs/de/benchmark/tanstack.md +12 -3
- package/docs/de/benchmark/vue.md +160 -0
- package/docs/de/configuration.md +16 -12
- package/docs/de/dictionary/content_file.md +52 -2
- package/docs/de/plugins/sync-po.md +0 -22
- package/docs/en/benchmark/nextjs.md +11 -2
- package/docs/en/benchmark/solid.md +22 -4
- package/docs/en/benchmark/svelte.md +17 -5
- package/docs/en/benchmark/tanstack.md +18 -3
- package/docs/en/benchmark/vue.md +17 -11
- package/docs/en/configuration.md +16 -13
- package/docs/en/dictionary/content_file.md +51 -1
- package/docs/en/plugins/sync-po.md +0 -21
- package/docs/en-GB/benchmark/index.md +0 -3
- package/docs/en-GB/benchmark/nextjs.md +15 -6
- package/docs/en-GB/benchmark/solid.md +155 -0
- package/docs/en-GB/benchmark/svelte.md +148 -0
- package/docs/en-GB/benchmark/tanstack.md +12 -3
- package/docs/en-GB/benchmark/vue.md +160 -0
- package/docs/en-GB/configuration.md +15 -11
- package/docs/en-GB/dictionary/content_file.md +51 -1
- package/docs/en-GB/plugins/sync-po.md +0 -21
- package/docs/es/benchmark/index.md +0 -3
- package/docs/es/benchmark/nextjs.md +15 -6
- package/docs/es/benchmark/solid.md +155 -0
- package/docs/es/benchmark/svelte.md +148 -0
- package/docs/es/benchmark/tanstack.md +12 -3
- package/docs/es/benchmark/vue.md +160 -0
- package/docs/es/configuration.md +16 -12
- package/docs/es/dictionary/content_file.md +51 -1
- package/docs/es/plugins/sync-po.md +0 -21
- package/docs/fr/benchmark/index.md +0 -3
- package/docs/fr/benchmark/nextjs.md +15 -6
- package/docs/fr/benchmark/solid.md +155 -0
- package/docs/fr/benchmark/svelte.md +148 -0
- package/docs/fr/benchmark/tanstack.md +12 -3
- package/docs/fr/benchmark/vue.md +160 -0
- package/docs/fr/configuration.md +16 -12
- package/docs/fr/dictionary/content_file.md +51 -1
- package/docs/fr/plugins/sync-po.md +0 -21
- package/docs/hi/benchmark/nextjs.md +15 -6
- package/docs/hi/benchmark/solid.md +155 -0
- package/docs/hi/benchmark/svelte.md +148 -0
- package/docs/hi/benchmark/tanstack.md +12 -3
- package/docs/hi/benchmark/vue.md +160 -0
- package/docs/hi/configuration.md +16 -12
- package/docs/hi/dictionary/content_file.md +51 -1
- package/docs/hi/plugins/sync-po.md +0 -21
- package/docs/id/benchmark/index.md +0 -3
- package/docs/id/benchmark/nextjs.md +15 -6
- package/docs/id/benchmark/solid.md +155 -0
- package/docs/id/benchmark/svelte.md +148 -0
- package/docs/id/benchmark/tanstack.md +12 -3
- package/docs/id/benchmark/vue.md +160 -0
- package/docs/id/configuration.md +16 -12
- package/docs/id/dictionary/content_file.md +51 -1
- package/docs/id/plugins/sync-po.md +0 -21
- package/docs/it/benchmark/index.md +1 -4
- package/docs/it/benchmark/nextjs.md +15 -6
- package/docs/it/benchmark/solid.md +155 -0
- package/docs/it/benchmark/svelte.md +148 -0
- package/docs/it/benchmark/tanstack.md +12 -3
- package/docs/it/benchmark/vue.md +160 -0
- package/docs/it/configuration.md +16 -12
- package/docs/it/dictionary/content_file.md +51 -1
- package/docs/it/plugins/sync-po.md +0 -21
- package/docs/ja/benchmark/index.md +5 -5
- package/docs/ja/benchmark/nextjs.md +15 -6
- package/docs/ja/benchmark/solid.md +155 -0
- package/docs/ja/benchmark/svelte.md +148 -0
- package/docs/ja/benchmark/tanstack.md +12 -3
- package/docs/ja/benchmark/vue.md +160 -0
- package/docs/ja/configuration.md +16 -12
- package/docs/ja/dictionary/content_file.md +50 -2
- package/docs/ja/intlayer_with_nextjs_no_locale_path.md +4 -3
- package/docs/ja/plugins/sync-po.md +0 -21
- package/docs/ko/benchmark/nextjs.md +15 -6
- package/docs/ko/benchmark/solid.md +155 -0
- package/docs/ko/benchmark/svelte.md +148 -0
- package/docs/ko/benchmark/tanstack.md +12 -3
- package/docs/ko/benchmark/vue.md +160 -0
- package/docs/ko/configuration.md +16 -12
- package/docs/ko/dictionary/content_file.md +51 -1
- package/docs/ko/intlayer_with_nextjs_no_locale_path.md +3 -2
- package/docs/ko/plugins/sync-po.md +0 -21
- package/docs/nl/configuration.md +16 -12
- package/docs/pl/benchmark/index.md +0 -3
- package/docs/pl/benchmark/nextjs.md +15 -6
- package/docs/pl/benchmark/solid.md +155 -0
- package/docs/pl/benchmark/svelte.md +148 -0
- package/docs/pl/benchmark/tanstack.md +12 -3
- package/docs/pl/benchmark/vue.md +160 -0
- package/docs/pl/configuration.md +16 -12
- package/docs/pl/dictionary/content_file.md +51 -1
- package/docs/pl/plugins/sync-po.md +0 -21
- package/docs/pt/benchmark/index.md +0 -3
- package/docs/pt/benchmark/nextjs.md +16 -7
- package/docs/pt/benchmark/solid.md +155 -0
- package/docs/pt/benchmark/svelte.md +148 -0
- package/docs/pt/benchmark/tanstack.md +13 -4
- package/docs/pt/benchmark/vue.md +160 -0
- package/docs/pt/configuration.md +16 -12
- package/docs/pt/dictionary/content_file.md +51 -1
- package/docs/pt/plugins/sync-po.md +0 -21
- package/docs/ru/benchmark/nextjs.md +15 -6
- package/docs/ru/benchmark/solid.md +155 -0
- package/docs/ru/benchmark/svelte.md +148 -0
- package/docs/ru/benchmark/tanstack.md +12 -3
- package/docs/ru/benchmark/vue.md +160 -0
- package/docs/ru/configuration.md +16 -12
- package/docs/ru/dictionary/content_file.md +52 -2
- package/docs/ru/plugins/sync-po.md +0 -21
- package/docs/tr/benchmark/index.md +0 -3
- package/docs/tr/benchmark/nextjs.md +15 -6
- package/docs/tr/benchmark/solid.md +155 -0
- package/docs/tr/benchmark/svelte.md +148 -0
- package/docs/tr/benchmark/tanstack.md +12 -3
- package/docs/tr/benchmark/vue.md +160 -0
- package/docs/tr/configuration.md +16 -12
- package/docs/tr/dictionary/content_file.md +51 -1
- package/docs/tr/plugins/sync-po.md +0 -21
- package/docs/uk/benchmark/nextjs.md +15 -6
- package/docs/uk/benchmark/solid.md +155 -0
- package/docs/uk/benchmark/svelte.md +148 -0
- package/docs/uk/benchmark/tanstack.md +12 -3
- package/docs/uk/benchmark/vue.md +160 -0
- package/docs/uk/configuration.md +16 -12
- package/docs/uk/dictionary/content_file.md +51 -1
- package/docs/uk/plugins/sync-po.md +0 -21
- package/docs/ur/configuration.md +16 -12
- package/docs/vi/benchmark/index.md +0 -3
- package/docs/vi/benchmark/nextjs.md +15 -6
- package/docs/vi/benchmark/solid.md +155 -0
- package/docs/vi/benchmark/svelte.md +148 -0
- package/docs/vi/benchmark/tanstack.md +12 -3
- package/docs/vi/benchmark/vue.md +160 -0
- package/docs/vi/configuration.md +16 -12
- package/docs/vi/dictionary/content_file.md +51 -1
- package/docs/vi/intlayer_with_nextjs_15.md +10 -57
- package/docs/vi/plugins/sync-po.md +0 -21
- package/docs/zh/benchmark/nextjs.md +15 -6
- package/docs/zh/benchmark/solid.md +155 -0
- package/docs/zh/benchmark/svelte.md +148 -0
- package/docs/zh/benchmark/tanstack.md +12 -3
- package/docs/zh/benchmark/vue.md +160 -0
- package/docs/zh/configuration.md +16 -12
- package/docs/zh/dictionary/content_file.md +51 -3
- package/docs/zh/plugins/sync-po.md +0 -21
- package/frequent_questions/ar/intlayerNode.md +3 -3
- package/frequent_questions/de/intlayerNode.md +3 -3
- package/frequent_questions/en/intlayerNode.md +3 -3
- package/frequent_questions/en-GB/intlayerNode.md +3 -3
- package/frequent_questions/es/intlayerNode.md +3 -3
- package/frequent_questions/fr/intlayerNode.md +3 -3
- package/frequent_questions/hi/intlayerNode.md +3 -3
- package/frequent_questions/id/intlayerNode.md +3 -3
- package/frequent_questions/it/intlayerNode.md +3 -3
- package/frequent_questions/ja/intlayerNode.md +3 -3
- package/frequent_questions/ko/intlayerNode.md +3 -3
- package/frequent_questions/pl/intlayerNode.md +3 -3
- package/frequent_questions/pt/intlayerNode.md +3 -3
- package/frequent_questions/ru/intlayerNode.md +3 -3
- package/frequent_questions/tr/intlayerNode.md +3 -3
- package/frequent_questions/uk/intlayerNode.md +3 -3
- package/frequent_questions/vi/intlayerNode.md +3 -3
- package/frequent_questions/zh/intlayerNode.md +3 -3
- package/package.json +8 -8
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: La mejor solución i18n para Solid en 2026 - Informe de Benchmark
|
|
5
|
+
description: Compara bibliotecas de internacionalización (i18n) para Solid como solid-primitives, solid-i18next e Intlayer. Informe de rendimiento detallado sobre el tamaño del paquete, fugas y reactividad.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- solid
|
|
11
|
+
- rendimiento
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- solid
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-solid-template
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.12
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "Inicialización del benchmark"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Bibliotecas i18n para Solid — Informe de Benchmark 2026
|
|
26
|
+
|
|
27
|
+
Esta página es un informe de benchmark para soluciones de i18n en Solid.
|
|
28
|
+
|
|
29
|
+
## Tabla de Contenidos
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## Benchmark Interactivo
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="vite-solid" vertical/>
|
|
36
|
+
|
|
37
|
+
## Referencia de resultados:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_solid.md"
|
|
41
|
+
width="100%"
|
|
42
|
+
height="600px"
|
|
43
|
+
style="border:none;">
|
|
44
|
+
</iframe>
|
|
45
|
+
|
|
46
|
+
> https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_solid.md
|
|
47
|
+
|
|
48
|
+
Vea el repositorio completo del benchmark [aquí](https://github.com/intlayer-org/benchmark-i18n/tree/main).
|
|
49
|
+
|
|
50
|
+
## Introducción
|
|
51
|
+
|
|
52
|
+
Las soluciones de internacionalización se encuentran entre las dependencias más pesadas en una aplicación Solid. El riesgo principal es enviar contenido innecesario: traducciones para otras páginas y otros idiomas en el paquete de una sola ruta.
|
|
53
|
+
|
|
54
|
+
A medida que su aplicación crece, ese problema puede aumentar rápidamente el JavaScript enviado al cliente y ralentizar la navegación.
|
|
55
|
+
|
|
56
|
+
En la práctica, para las implementaciones menos optimizadas, una página internacionalizada puede terminar siendo varias veces más pesada que la versión sin i18n.
|
|
57
|
+
|
|
58
|
+
El otro impacto es en la experiencia del desarrollador (DX): cómo se declara el contenido, los tipos, la organización de los namespaces, la carga dinámica y la reactividad cuando cambia el idioma.
|
|
59
|
+
|
|
60
|
+
## TL;DR
|
|
61
|
+
|
|
62
|
+
- **Intlayer**: Opción recomendada para aplicaciones Solid profesionales que necesitan características avanzadas y optimización (v8.7.12).
|
|
63
|
+
- **@solid-primitives/i18n**: Excelente alternativa ligera para proyectos simples, aunque carece de características avanzadas como la carga diferida (lazy loading).
|
|
64
|
+
- **solid-i18next**: Opción estándar pero pesada (~4.7× Intlayer) con los mismos inconvenientes que React i18next.
|
|
65
|
+
- **Paraglide**: Enfoque innovador pero DX compleja y problemas de tree-shaking en algunas configuraciones.
|
|
66
|
+
|
|
67
|
+
## Pruebe su aplicación
|
|
68
|
+
|
|
69
|
+
Para detectar rápidamente problemas de fugas de i18n, he configurado un escáner gratuito disponible [aquí](https://intlayer.org/i18n-seo-scanner).
|
|
70
|
+
|
|
71
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
72
|
+
|
|
73
|
+
## El problema
|
|
74
|
+
|
|
75
|
+
Dos palancas son esenciales para limitar el costo de una aplicación multilingüe:
|
|
76
|
+
|
|
77
|
+
- Dividir el contenido por página / namespace para no cargar diccionarios completos cuando no se necesitan.
|
|
78
|
+
- Cargar el idioma correcto dinámicamente, solo cuando sea necesario.
|
|
79
|
+
|
|
80
|
+
Comprender las limitaciones técnicas de estos enfoques:
|
|
81
|
+
|
|
82
|
+
**Carga dinámica**
|
|
83
|
+
|
|
84
|
+
Sin carga dinámica, la mayoría de las soluciones mantienen los mensajes en memoria desde el primer renderizado, lo que añade una sobrecarga significativa para aplicaciones con muchas rutas e idiomas.
|
|
85
|
+
|
|
86
|
+
Con la carga dinámica, se acepta un compromiso: menos JS inicial, pero a veces una solicitud adicional al cambiar de idioma.
|
|
87
|
+
|
|
88
|
+
**División de contenido (Splitting)**
|
|
89
|
+
|
|
90
|
+
Las sintaxis construidas en torno a `t('a.b.c')` son muy convenientes pero a menudo fomentan el mantenimiento de grandes objetos JSON en tiempo de ejecución. Ese modelo dificulta el tree-shaking a menos que la biblioteca ofrezca una estrategia real de división por página.
|
|
91
|
+
|
|
92
|
+
## Metodología
|
|
93
|
+
|
|
94
|
+
Para este benchmark, comparamos las siguientes bibliotecas:
|
|
95
|
+
|
|
96
|
+
- `Base App` (Sin biblioteca i18n)
|
|
97
|
+
- `solid-intlayer` (v8.7.12)
|
|
98
|
+
- `@solid-primitives/i18n` (v2.2.1)
|
|
99
|
+
- `solid-i18next` (v17.0.2)
|
|
100
|
+
- `@inlang/paraglide-js` (v2.17.0)
|
|
101
|
+
|
|
102
|
+
El framework es `Solid` con una aplicación multilingüe de **10 páginas** y **10 idiomas**.
|
|
103
|
+
|
|
104
|
+
Comparamos **quatro estrategias de carga**:
|
|
105
|
+
|
|
106
|
+
| Estrategia | Sin namespaces (global) | Con namespaces (scoped) |
|
|
107
|
+
| :----------------- | :------------------------------------------ | :----------------------------------------------------------------- |
|
|
108
|
+
| **Carga estática** | **Static**: Todo en memoria al inicio. | **Scoped static**: Dividido por namespace; todo cargado al inicio. |
|
|
109
|
+
| **Carga dinámica** | **Dynamic**: Carga bajo demanda por idioma. | **Scoped dynamic**: Carga granular por namespace e idioma. |
|
|
110
|
+
|
|
111
|
+
## Resumen de estrategias
|
|
112
|
+
|
|
113
|
+
- **Static**: Simple; sin latencia de red después de la carga inicial. Desventaja: gran tamaño del paquete.
|
|
114
|
+
- **Dynamic**: Reduce el peso inicial (lazy-loading). Ideal cuando se tienen muchos idiomas.
|
|
115
|
+
- **Scoped static**: Mantiene el código organizado (separación lógica) sin solicitudes de red adicionales complejas.
|
|
116
|
+
- **Scoped dynamic**: El mejor enfoque para el _code splitting_ y el rendimiento. Minimiza la memoria cargando solo lo que la vista actual y el idioma activo necesitan.
|
|
117
|
+
|
|
118
|
+
## Resultados detallados
|
|
119
|
+
|
|
120
|
+
### 1 — Soluciones a evitar
|
|
121
|
+
|
|
122
|
+
> No hay una solución clara a evitar en el ecosistema de Solid.
|
|
123
|
+
|
|
124
|
+
### 2 — Soluciones aceptables
|
|
125
|
+
|
|
126
|
+
**(solid-i18next)** (`solid-i18next@17.0.2`):
|
|
127
|
+
|
|
128
|
+
`solid-i18next` es probablemente la opción más popular porque fue una de las primeras en satisfacer las necesidades de i18n de las aplicaciones de JavaScript. También cuenta con un amplio conjunto de complementos de la comunidad para problemas específicos.
|
|
129
|
+
|
|
130
|
+
El paquete es pesado (~14.6kb, aproximadamente 4.7 veces `solid-intlayer`).
|
|
131
|
+
|
|
132
|
+
Aun así, comparte las mismas desventajas principales que las pilas construidas sobre `t('a.b.c')`: las optimizaciones son posibles pero requieren mucho tiempo, y los proyectos grandes corren el riesgo de malas prácticas (namespaces + carga dinámica + tipos).
|
|
133
|
+
|
|
134
|
+
**(@solid-primitives/i18n)** (`@solid-primitives/i18n@2.2.1`):
|
|
135
|
+
|
|
136
|
+
Solid primitive es extremadamente ligero y eficiente. Recomiendo esa solución para proyectos ligeros, pero puede carecer rápidamente de características para soluciones profesionales que incluyan gestión de cookies, redirección de proxy, formateadores, etc.
|
|
137
|
+
También carece de carga diferida (lazy loading) y segmentación de namespaces para la optimización del tamaño de la página.
|
|
138
|
+
|
|
139
|
+
**(Paraglide)** (`@inlang/paraglide-js@2.17.0`):
|
|
140
|
+
|
|
141
|
+
`Paraglide` ofrece un enfoque innovador y bien pensado. Aun así, en este benchmark, el tree-shaking que su empresa publicita no funcionó para mi implementación. El flujo de trabajo y la DX también son más complejos que en otras opciones.
|
|
142
|
+
Personalmente, no me gusta tener que regenerar archivos JS antes de cada push, lo que genera un riesgo constante de conflictos de fusión a través de los PR.
|
|
143
|
+
Finalmente, en comparación con otras soluciones, Paraglide no utiliza un almacén (ej. Solid signal) para recuperar el idioma actual para renderizar el contenido. Para cada nodo analizado, solicitará el idioma al localStorage / cookie, etc. Esto conduce a la ejecución de lógica innecesaria que impacta la reactividad del componente.
|
|
144
|
+
|
|
145
|
+
### 3 — Recomendaciones
|
|
146
|
+
|
|
147
|
+
**(Intlayer)** (`solid-intlayer@8.7.12`):
|
|
148
|
+
|
|
149
|
+
No juzgaré personalmente `solid-intlayer` por objetividad, ya que es mi propia solución.
|
|
150
|
+
|
|
151
|
+
### Nota personal
|
|
152
|
+
|
|
153
|
+
Esta nota es personal y no afecta los resultados del benchmark. Aun así, en el mundo del i18n a menudo se ve consenso en torno a un patrón como `const t = useTranslation('xx')` + `<>{t('xx.xx')}</>` para el contenido traducido.
|
|
154
|
+
|
|
155
|
+
En las aplicaciones Solid, inyectar una función como un `JSX.Element` es, en mi opinión, un antipatrón. También añade complejidad evitable y sobrecarga de ejecución de JavaScript (aunque sea apenas perceptible).
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: La mejor solución i18n para Svelte en 2026 - Informe de Benchmark
|
|
5
|
+
description: Compara bibliotecas de internacionalización (i18n) para Svelte como svelte-i18n, Paraglide e Intlayer. Informe de rendimiento detallado sobre el tamaño del paquete, fugas y reactividad.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- svelte
|
|
11
|
+
- rendimiento
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- svelte
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-svelte-template
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.12
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "Inicialización del benchmark"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Bibliotecas i18n para Svelte — Informe de Benchmark 2026
|
|
26
|
+
|
|
27
|
+
Esta página es un informe de benchmark para soluciones de i18n en Svelte.
|
|
28
|
+
|
|
29
|
+
## Tabla de Contenidos
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## Benchmark Interactivo
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="vite-svelte" vertical/>
|
|
36
|
+
|
|
37
|
+
## Referencia de resultados:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_svelte.md"
|
|
41
|
+
width="100%"
|
|
42
|
+
height="600px"
|
|
43
|
+
style="border:none;">
|
|
44
|
+
</iframe>
|
|
45
|
+
|
|
46
|
+
> https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_svelte.md
|
|
47
|
+
|
|
48
|
+
Vea el repositorio completo del benchmark [aquí](https://github.com/intlayer-org/benchmark-i18n/tree/main).
|
|
49
|
+
|
|
50
|
+
## Introducción
|
|
51
|
+
|
|
52
|
+
Las soluciones de internacionalización se encuentran entre las dependencias más pesadas en una aplicación Svelte. El riesgo principal es enviar contenido innecesario: traducciones para otras páginas y otros idiomas en el paquete de una sola ruta.
|
|
53
|
+
|
|
54
|
+
A medida que su aplicación crece, ese problema puede aumentar rápidamente el JavaScript enviado al cliente y ralentizar la navegación.
|
|
55
|
+
|
|
56
|
+
En la práctica, para las implementaciones menos optimizadas, una página internacionalizada puede terminar siendo varias veces más pesada que la versión sin i18n.
|
|
57
|
+
|
|
58
|
+
El otro impacto es en la experiencia del desarrollador (DX): cómo se declara el contenido, los tipos, la organización de los namespaces, la carga dinámica y la reactividad cuando cambia el idioma.
|
|
59
|
+
|
|
60
|
+
## TL;DR
|
|
61
|
+
|
|
62
|
+
- **Intlayer**: La opción más eficiente en cuanto a rendimiento (v8.7.12) con la menor huella.
|
|
63
|
+
- **Paraglide**: Candidato fuerte para el tree-shaking pero tiene una experiencia de desarrollador más compleja y sobrecarga de reactividad.
|
|
64
|
+
- **svelte-i18n**: Completo y estándar para Svelte, pero conlleva un peso de paquete mucho mayor (~7 veces Intlayer).
|
|
65
|
+
|
|
66
|
+
## Pruebe su aplicación
|
|
67
|
+
|
|
68
|
+
Para detectar rápidamente problemas de fugas de i18n, he configurado un escáner gratuito disponible [aquí](https://intlayer.org/i18n-seo-scanner).
|
|
69
|
+
|
|
70
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
71
|
+
|
|
72
|
+
## El problema
|
|
73
|
+
|
|
74
|
+
Dos palancas son esenciales para limitar el costo de una aplicación multilingüe:
|
|
75
|
+
|
|
76
|
+
- Dividir el contenido por página / namespace para no cargar diccionarios completos cuando no se necesitan.
|
|
77
|
+
- Cargar el idioma correcto dinámicamente, solo cuando sea necesario.
|
|
78
|
+
|
|
79
|
+
Comprender las limitaciones técnicas de estos enfoques:
|
|
80
|
+
|
|
81
|
+
**Carga dinámica**
|
|
82
|
+
|
|
83
|
+
Sin carga dinámica, la mayoría de las soluciones mantienen los mensajes en memoria desde el primer renderizado, lo que añade una sobrecarga significativa para aplicaciones con muchas rutas e idiomas.
|
|
84
|
+
|
|
85
|
+
Con la carga dinámica, se acepta un compromiso: menos JS inicial, pero a veces una solicitud adicional al cambiar de idioma.
|
|
86
|
+
|
|
87
|
+
**División de contenido (Splitting)**
|
|
88
|
+
|
|
89
|
+
Las sintaxis construidas en torno a `t('a.b.c')` son muy convenientes pero a menudo fomentan el mantenimiento de grandes objetos JSON en tiempo de ejecución. Ese modelo dificulta el tree-shaking a menos que la biblioteca ofrezca una estrategia real de división por página.
|
|
90
|
+
|
|
91
|
+
## Metodología
|
|
92
|
+
|
|
93
|
+
Para este benchmark, comparamos las siguientes bibliotecas:
|
|
94
|
+
|
|
95
|
+
- `Base App` (Sin biblioteca i18n)
|
|
96
|
+
- `svelte-intlayer` (v8.7.12)
|
|
97
|
+
- `svelte-i18n` (v4.0.1)
|
|
98
|
+
- `@inlang/paraglide-js` (v2.17.0)
|
|
99
|
+
|
|
100
|
+
El framework es `Svelte` con una aplicación multilingüe de **10 páginas** y **10 idiomas**.
|
|
101
|
+
|
|
102
|
+
Comparamos **quatro estrategias de carga**:
|
|
103
|
+
|
|
104
|
+
| Estrategia | Sin namespaces (global) | Con namespaces (scoped) |
|
|
105
|
+
| :----------------- | :------------------------------------------ | :----------------------------------------------------------------- |
|
|
106
|
+
| **Carga estática** | **Static**: Todo en memoria al inicio. | **Scoped static**: Dividido por namespace; todo cargado al inicio. |
|
|
107
|
+
| **Carga dinámica** | **Dynamic**: Carga bajo demanda por idioma. | **Scoped dynamic**: Carga granular por namespace e idioma. |
|
|
108
|
+
|
|
109
|
+
## Resumen de estrategias
|
|
110
|
+
|
|
111
|
+
- **Static**: Simple; sin latencia de red después de la carga inicial. Desventaja: gran tamaño del paquete.
|
|
112
|
+
- **Dynamic**: Reduce el peso inicial (lazy-loading). Ideal cuando se tienen muchos idiomas.
|
|
113
|
+
- **Scoped static**: Mantiene el código organizado (separación lógica) sin solicitudes de red adicionales complejas.
|
|
114
|
+
- **Scoped dynamic**: El mejor enfoque para el _code splitting_ y el rendimiento. Minimiza la memoria cargando solo lo que la vista actual y el idioma activo necesitan.
|
|
115
|
+
|
|
116
|
+
## Resultados detallados
|
|
117
|
+
|
|
118
|
+
### 1 — Soluciones a evitar
|
|
119
|
+
|
|
120
|
+
> No hay una solución clara a evitar en el ecosistema de Svelte.
|
|
121
|
+
|
|
122
|
+
### 2 — Soluciones aceptables
|
|
123
|
+
|
|
124
|
+
**(Paraglide)** (`@inlang/paraglide-js@2.17.0`):
|
|
125
|
+
|
|
126
|
+
`Paraglide` ofrece un enfoque innovador y bien pensado. En el contexto de una aplicación Vite + Svelte, el tree-shaking que su empresa publicita funcionó como se esperaba, lo cual es excelente.
|
|
127
|
+
Pero en el caso de React + TanStack Start, el tree-shaking no funcionó como se esperaba, lo mismo para Next.js. Dicho esto, valdría la pena volver a verificar el uso de Paraglide en un proyecto Svelte y TanStack Start.
|
|
128
|
+
El flujo de trabajo y la DX también son más complejos que en otras opciones.
|
|
129
|
+
Personalmente, no me gusta tener que regenerar archivos JS antes de cada push, lo que genera un riesgo constante de conflictos de fusión a través de los PR. La herramienta también parece estar más centrada en Vite que en Next.js.
|
|
130
|
+
Finalmente, en comparación con otras soluciones, Paraglide no utiliza un almacén (ej. Svelte store) para recuperar el idioma actual para renderizar el contenido. Para cada nodo analizado, solicitará el idioma al localStorage / cookie, etc. Esto conduce a la ejecución de lógica innecesaria que impacta la reactividad del componente.
|
|
131
|
+
|
|
132
|
+
> Nota sobre paraglide: la solución inyecta código en su base de código para las importaciones; como resultado, la métrica 'lib size' en el informe de benchmark es casi 0. La generación de código es algo bueno, porque la función utilizada incluirá solo la lógica necesaria (prefijo en todas partes vs sin prefijo, cookie vs almacenamiento, etc.). En comparación, Intlayer realiza este filtrado mediante inyecciones de variables de entorno durante la compilación para obligar al bundler a realizar tree-shaking del contenido según la lógica. Gracias a esto, paraglide e intlayer terminan siendo soluciones de 6 a 10 veces más ligeras que i18next o next-intl.
|
|
133
|
+
|
|
134
|
+
**(svelte-i18n)** (`svelte-i18n@3.4.0`):
|
|
135
|
+
|
|
136
|
+
Esta solución satisface todas las necesidades de i18n en un proyecto Svelte. Pero como es el caso de i18next u otras soluciones importantes, es un poco pesada (~15.9kb, aproximadamente 7 veces `svelte-intlayer`).
|
|
137
|
+
|
|
138
|
+
### 3 — Recomendaciones
|
|
139
|
+
|
|
140
|
+
**(Intlayer)** (`svelte-intlayer@8.7.12`):
|
|
141
|
+
|
|
142
|
+
No juzgaré personalmente `svelte-intlayer` por objetividad, ya que es mi propia solución.
|
|
143
|
+
|
|
144
|
+
### Nota personal
|
|
145
|
+
|
|
146
|
+
Esta nota es personal y no afecta los resultados del benchmark. Aun así, en el mundo del i18n a menudo se ve consenso en torno a un patrón como `const t = useTranslation('xx')` + `<>{t('xx.xx')}</>` para el contenido traducido.
|
|
147
|
+
|
|
148
|
+
En las aplicaciones Svelte, inyectar una función como un `Slot` es, en mi opinión, un antipatrón. También añade complejidad evitable y sobrecarga de ejecución de JavaScript (aunque sea apenas perceptible).
|
|
@@ -57,6 +57,13 @@ En la práctica, en las implementaciones menos optimizadas, una página internac
|
|
|
57
57
|
|
|
58
58
|
El otro impacto es en la experiencia del desarrollador: cómo declaras el contenido, los tipos, la organización de los namespaces, la carga dinámica y la reactividad cuando cambia el idioma.
|
|
59
59
|
|
|
60
|
+
## TL;DR
|
|
61
|
+
|
|
62
|
+
- **Intlayer**: Proporciona el mejor rendimiento y el tamaño de bundle más pequeño (v8.7.12) para TanStack Start.
|
|
63
|
+
- **react-i18next** & **use-intl**: Alternativas maduras con grandes ecosistemas, mas significativamente más pesadas y complejas de optimizar.
|
|
64
|
+
- **Paraglide**: Idea innovadora de tree-shaking que no funciona en la práctica. DX compleja y sobrecarga de reactividad en TanStack Start.
|
|
65
|
+
- **Evitar**: **General Translation (GT)** y **Lingo.dev** debido a graves problemas de rendimiento, límites de cuota de IA y bloqueo del proveedor (vendor lock-in).
|
|
66
|
+
|
|
60
67
|
## Pon a prueba tu aplicación
|
|
61
68
|
|
|
62
69
|
Para detectar rápidamente problemas de fuga de i18n, he configurado un escáner gratuito disponible [aquí](https://intlayer.org/i18n-seo-scanner).
|
|
@@ -87,12 +94,12 @@ Las sintaxis basadas en `const t = useTranslation()` + `t('a.b.c')` son muy cóm
|
|
|
87
94
|
Para este benchmark, comparamos las siguientes librerías:
|
|
88
95
|
|
|
89
96
|
- `Base App` (Sin librería i18n)
|
|
90
|
-
- `react-intlayer` (v8.7.
|
|
97
|
+
- `react-intlayer` (v8.7.12)
|
|
91
98
|
- `react-i18next` (v17.0.2)
|
|
92
99
|
- `use-intl` (v4.9.1)
|
|
93
100
|
- `@lingui/core` (v5.3.0)
|
|
94
101
|
- `@inlang/paraglide-js` (v2.15.1)
|
|
95
|
-
-
|
|
102
|
+
- `@tolgee/react` (v7.0.0)
|
|
96
103
|
- `react-intl` (v10.1.1)
|
|
97
104
|
- `wuchale` (v0.22.11)
|
|
98
105
|
- `gt-react` (vlatest)
|
|
@@ -150,7 +157,9 @@ La idea detrás de `Wuchale` es interesante pero todavía no es una solución vi
|
|
|
150
157
|
|
|
151
158
|
`Paraglide` ofrece un enfoque innovador y bien pensado. Aun así, en este benchmark, el tree-shaking que su empresa publicita no funcionó para mi implementación en Next.js ni para TanStack Start. El flujo de trabajo y la DX también son más complejos que otras opciones. Personalmente, no soy fan de tener que regenerar archivos JS antes de cada push, lo que crea un riesgo constante de conflictos de fusión para los desarrolladores a través de las PR.
|
|
152
159
|
|
|
153
|
-
|
|
160
|
+
> Nota sobre paraglide: la solución inyecta código en tu base de código para las importaciones, como resultado, la métrica 'lib size' en el informe del benchmark es casi 0. La generación de código es algo bueno, porque la función utilizada incluirá solo la lógica necesaria (prefijo para todo vs sin prefijo, cookie vs almacenamiento, etc.). En comparación, Intlayer realiza este filtrado mediante inyecciones de variables de entorno en la compilación para forzar al bundler a realizar tree-shake del contenido dependiendo de la lógica. Gracias a esto, paraglide e intlayer terminan siendo soluciones entre 6 y 10 veces más ligeras que i18next o next-intl.
|
|
161
|
+
|
|
162
|
+
**(Tolgee)** (`@tolgee/react@7.0.0`):
|
|
154
163
|
|
|
155
164
|
`Tolgee` aborda muchos de los problemas mencionados anteriormente. Me resultó más difícil empezar con ella que con otras herramientas con enfoques similares. No proporciona seguridad de tipos, lo que también dificulta mucho detectar claves faltantes en tiempo de compilación. Tuve que envolver las API de Tolgee con las mías propias para añadir la detección de claves faltantes.
|
|
156
165
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: La mejor solución i18n para Vue en 2026 - Informe de Benchmark
|
|
5
|
+
description: Compara bibliotecas de internacionalización (i18n) para Vue como vue-i18n, fluent-vue e Intlayer. Informe de rendimiento detallado sobre el tamaño del paquete, fugas y reactividad.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- vue
|
|
11
|
+
- rendimiento
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- vue
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-vue-template
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.12
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "Inicialización del benchmark"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Bibliotecas i18n para Vue — Informe de Benchmark 2026
|
|
26
|
+
|
|
27
|
+
Esta página es un informe de benchmark para soluciones de i18n en Vue.
|
|
28
|
+
|
|
29
|
+
## Tabla de Contenidos
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## Benchmark Interactivo
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="vite-vue" vertical/>
|
|
36
|
+
|
|
37
|
+
## Referencia de resultados:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_vue.md"
|
|
41
|
+
width="100%"
|
|
42
|
+
height="600px"
|
|
43
|
+
style="border:none;">
|
|
44
|
+
</iframe>
|
|
45
|
+
|
|
46
|
+
> https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_vue.md
|
|
47
|
+
|
|
48
|
+
Vea el repositorio completo del benchmark [aquí](https://github.com/intlayer-org/benchmark-i18n/tree/main).
|
|
49
|
+
|
|
50
|
+
## Introducción
|
|
51
|
+
|
|
52
|
+
Las soluciones de internacionalización se encuentran entre las dependencias más pesadas en una aplicación Vue. El riesgo principal es enviar contenido innecesario: traducciones para otras páginas y otros idiomas en el paquete de una sola ruta.
|
|
53
|
+
|
|
54
|
+
A medida que su aplicación crece, ese problema puede aumentar rápidamente el JavaScript enviado al cliente y ralentizar la navegación.
|
|
55
|
+
|
|
56
|
+
En la práctica, para las implementaciones menos optimizadas, una página internacionalizada puede terminar siendo varias veces más pesada que la versión sin i18n.
|
|
57
|
+
|
|
58
|
+
El otro impacto es en la experiencia del desarrollador (DX): cómo se declara el contenido, los tipos, la organización de los namespaces, la carga dinámica y la reactividad cuando cambia el idioma.
|
|
59
|
+
|
|
60
|
+
## TL;DR
|
|
61
|
+
|
|
62
|
+
- **Intlayer**: La solución más ligera (v8.7.12) con segmentación (scoping) y carga dinámica nativas.
|
|
63
|
+
- **vue-i18n**: El estándar de la industria con un ecosistema rico, pero puede ser significativamente más pesado y difícil de optimizar para el code-splitting en aplicaciones grandes.
|
|
64
|
+
- **fluent-vue**: Organización innovadora de mensajes pero carece de seguridad de tipos y resulta ser una solución extremadamente pesada.
|
|
65
|
+
|
|
66
|
+
## Pruebe su aplicación
|
|
67
|
+
|
|
68
|
+
Para detectar rápidamente problemas de fugas de i18n, he configurado un escáner gratuito disponible [aquí](https://intlayer.org/i18n-seo-scanner).
|
|
69
|
+
|
|
70
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
71
|
+
|
|
72
|
+
## El problema
|
|
73
|
+
|
|
74
|
+
Dos palancas son esenciales para limitar el costo de una aplicación multilingüe:
|
|
75
|
+
|
|
76
|
+
- Dividir el contenido por página / namespace para no cargar diccionarios completos cuando no se necesitan.
|
|
77
|
+
- Cargar el idioma correcto dinámicamente, solo cuando sea necesario.
|
|
78
|
+
|
|
79
|
+
Comprender las limitaciones técnicas de estos enfoques:
|
|
80
|
+
|
|
81
|
+
**Carga dinámica**
|
|
82
|
+
|
|
83
|
+
Sin carga dinámica, la mayoría de las soluciones mantienen los mensajes en memoria desde el primer renderizado, lo que añade una sobrecarga significativa para aplicaciones con muchas rutas e idiomas.
|
|
84
|
+
|
|
85
|
+
Con la carga dinámica, se acepta un compromiso: menos JS inicial, pero a veces una solicitud adicional al cambiar de idioma.
|
|
86
|
+
|
|
87
|
+
**División de contenido (Splitting)**
|
|
88
|
+
|
|
89
|
+
Las sintaxis construidas en torno a `const { t } = useI18n()` + `t('a.b.c')` son muy convenientes pero a menudo fomentan el mantenimiento de grandes objetos JSON en tiempo de ejecución. Ese modelo dificulta el tree-shaking a menos que la biblioteca ofrezca una estrategia real de división por página.
|
|
90
|
+
|
|
91
|
+
## Metodología
|
|
92
|
+
|
|
93
|
+
Para este benchmark, comparamos las siguientes bibliotecas:
|
|
94
|
+
|
|
95
|
+
- `Base App` (Sin biblioteca i18n)
|
|
96
|
+
- `vue-intlayer` (v8.7.12)
|
|
97
|
+
- `vue-i18n` (v11.4.0)
|
|
98
|
+
- `fluent-vue` (v3.8.2)
|
|
99
|
+
|
|
100
|
+
El framework es `Vue` con una aplicación multilingüe de **10 páginas** y **10 idiomas**.
|
|
101
|
+
|
|
102
|
+
Comparamos **cuatro estrategias de carga**:
|
|
103
|
+
|
|
104
|
+
| Estrategia | Sin namespaces (global) | Con namespaces (scoped) |
|
|
105
|
+
| :----------------- | :------------------------------------------ | :----------------------------------------------------------------- |
|
|
106
|
+
| **Carga estática** | **Static**: Todo en memoria al inicio. | **Scoped static**: Dividido por namespace; todo cargado al inicio. |
|
|
107
|
+
| **Carga dinámica** | **Dynamic**: Carga bajo demanda por idioma. | **Scoped dynamic**: Carga granular por namespace e idioma. |
|
|
108
|
+
|
|
109
|
+
## Resumen de estrategias
|
|
110
|
+
|
|
111
|
+
- **Static**: Simple; sin latencia de red después de la carga inicial. Desventaja: gran tamaño del paquete.
|
|
112
|
+
- **Dynamic**: Reduce el peso inicial (lazy-loading). Ideal cuando se tienen muchos idiomas.
|
|
113
|
+
- **Scoped static**: Mantiene el código organizado (separación lógica) sin solicitudes de red adicionales complejas.
|
|
114
|
+
- **Scoped dynamic**: El mejor enfoque para el _code splitting_ y el rendimiento. Minimiza la memoria cargando solo lo que la vista actual y el idioma activo necesitan.
|
|
115
|
+
|
|
116
|
+
### Lo que medí:
|
|
117
|
+
|
|
118
|
+
Ejecuté la misma aplicación multilingüe en un navegador real para cada stack y luego anoté lo que realmente pasó por la red y cuánto tiempo tomó. Los tamaños se informan **después de la compresión web normal**, ya que eso es más cercano a lo que la gente realmente descarga.
|
|
119
|
+
|
|
120
|
+
- **Tamaño de la biblioteca de internacionalización**: Después de la agrupación, tree-shaking y minificación, el tamaño de la biblioteca i18n es el tamaño del código de los providers + composables en un componente vacío. No incluye la carga de archivos de traducción. Responde a cuán "cara" es la biblioteca antes de que entre el contenido.
|
|
121
|
+
|
|
122
|
+
- **JavaScript por página**: Para cada ruta del benchmark, cuánto script extrae el navegador para esa visita, promediado entre las páginas de la suite (y entre idiomas). Las páginas pesadas son páginas lentas.
|
|
123
|
+
|
|
124
|
+
- **Fuga de otros idiomas (Leakage)**: Es el contenido de la misma página pero en otro idioma que se cargaría por error en la página auditada. Este contenido es innecesario y debe evitarse (ej. contenido de la página `/fr/about` en el paquete de la página `/en/about`).
|
|
125
|
+
|
|
126
|
+
- **Fuga de otras rutas**: La misma idea para **otras pantallas** de la aplicación: si sus textos se cargan cuando solo se abrió una página (ej. contenido de la página `/en/about` en el paquete de la página `/en/contact`). Una puntuación alta indica una división débil o paquetes demasiado amplios.
|
|
127
|
+
|
|
128
|
+
- **Tamaño promedio del paquete del componente**: Los elementos de interfaz comunes se miden **uno a la vez**, en lugar de ocultarse dentro de una cifra gigante de la aplicación. Muestra si la internacionalización infla silenciosamente los componentes cotidianos. Por ejemplo, si su componente se vuelve a renderizar, cargará todos esos datos desde la memoria. Adjuntar un JSON gigante a cualquier componente es como conectar un gran almacén de datos no utilizados que ralentizará el rendimiento de sus componentes.
|
|
129
|
+
|
|
130
|
+
- **Capacidad de respuesta al cambio de idioma**: Cambio el idioma utilizando el propio control de la aplicación y mido cuánto tiempo pasa hasta que la página ha cambiado claramente, lo que un visitante notaría.
|
|
131
|
+
|
|
132
|
+
- **Trabajo de renderizado tras un cambio de idioma**: Un seguimiento más detallado: cuánto esfuerzo le costó a la interfaz volver a dibujarse para el nuevo idioma una vez iniciado el cambio. Útil cuando el tiempo "percibido" y el costo del framework divergen.
|
|
133
|
+
|
|
134
|
+
- **Tiempo de carga inicial de la página**: Desde la navegación hasta que el navegador considera que la página está completamente cargada para los escenarios probados. Bueno para comparar arranques en frío.
|
|
135
|
+
|
|
136
|
+
- **Tiempo de hidratación (Hydration)**: Tiempo que pasa el cliente convirtiendo el HTML del servidor en una interfaz interactiva. Un guion en las tablas significa que esa implementación no proporcionó una cifra de hidratación fiable en este benchmark.
|
|
137
|
+
|
|
138
|
+
## Resultados en detalle
|
|
139
|
+
|
|
140
|
+
### 1 — Soluciones a evitar
|
|
141
|
+
|
|
142
|
+
> No hay una solución clara a evitar en el ecosistema de Vue.
|
|
143
|
+
|
|
144
|
+
### 2 — Soluciones aceptables
|
|
145
|
+
|
|
146
|
+
**(vue-i18n)** (`vue-i18n@11.4.0`):
|
|
147
|
+
|
|
148
|
+
- **vue-i18n** es sin duda la biblioteca de i18n más utilizada para Vue, tiene muchas características y un ecosistema enorme. Pero bajo el capó la solución es bastante pesada. Aunque vue-i18n integra carga diferida para los mensajes, carece de una función de segmentación (scoping). En el caso de una aplicación Vue SPA clásica no hay problema, pero para una aplicación Nuxt que utiliza @nuxt/i18n, esto lleva a incluir los mensajes de todas las páginas en una sola. Para una aplicación Nuxt grande con más de 10 páginas, puede volverse realmente problemático.
|
|
149
|
+
|
|
150
|
+
El paquete es muy pesado (~24.3kb, aproximadamente 9 veces `vue-intlayer`).
|
|
151
|
+
|
|
152
|
+
**(fluent-vue)** (`fluent-vue@0.5.0`):
|
|
153
|
+
|
|
154
|
+
- **fluent-vue** ofrece un intento de innovación a través del formato .ftl. La organización de los mensajes es excelente, más fácil de comenzar. Pero en la práctica, la falta de seguridad de tipos aumenta el riesgo de error y puede volverse rápidamente costoso de depurar. Además, esa solución carga los mensajes mediante un plugin de vite que obliga a cargar todo el contenido en todos los idiomas en cada página. Adicionalmente, es una solución extremadamente pesada (~92.7kb, aproximadamente 34 veces `vue-intlayer`).
|
|
155
|
+
|
|
156
|
+
### 3 — Recomendaciones
|
|
157
|
+
|
|
158
|
+
**(Intlayer)** (`vue-intlayer@8.7.12`):
|
|
159
|
+
|
|
160
|
+
No juzgaré personalmente `vue-intlayer` por objetividad, ya que es mi propia solución.
|
package/docs/es/configuration.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2024-08-13
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-05-12
|
|
4
4
|
title: Configuración (Configuration)
|
|
5
5
|
description: Aprenda a configure Intlayer para su aplicación. Entienda los diversos ajustes y opciones disponibles para personalizar Intlayer según sus necesidades.
|
|
6
6
|
keywords:
|
|
@@ -14,6 +14,9 @@ slugs:
|
|
|
14
14
|
- concept
|
|
15
15
|
- configuration
|
|
16
16
|
history:
|
|
17
|
+
- version: 8.9.4
|
|
18
|
+
date: 2026-05-12
|
|
19
|
+
changes: "Añadir soporte para el proveedor LM Studio"
|
|
17
20
|
- version: 8.7.0
|
|
18
21
|
date: 2026-04-08
|
|
19
22
|
changes: "Se añadieron las opciones `prune` y `minify` a la configuración de compilación"
|
|
@@ -350,7 +353,7 @@ const config: IntlayerConfig = {
|
|
|
350
353
|
ai: {
|
|
351
354
|
/**
|
|
352
355
|
* Proveedor de IA que se utilizará.
|
|
353
|
-
* Opciones: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai'
|
|
356
|
+
* Opciones: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai', 'lmstudio'
|
|
354
357
|
* Predeterminado: 'openai'
|
|
355
358
|
*/
|
|
356
359
|
provider: "openai",
|
|
@@ -918,16 +921,17 @@ Intlayer admite múltiples proveedores de IA para una flexibilidad máxima. Los
|
|
|
918
921
|
- **Groq**
|
|
919
922
|
- **Amazon Bedrock**
|
|
920
923
|
- **Together.ai**
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
|
924
|
-
|
|
|
925
|
-
| `
|
|
926
|
-
| `
|
|
927
|
-
| `
|
|
928
|
-
| `
|
|
929
|
-
| `
|
|
930
|
-
| `
|
|
924
|
+
- **LM Studio**
|
|
925
|
+
|
|
926
|
+
| Campo | Descripción | Tipo | Predeterminado | Ejemplo | Nota |
|
|
927
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
928
|
+
| `provider` | El proveedor que se usará para las funciones de IA de Intlayer. | `'openai'` | <br/> `'anthropic'` | <br/> `'mistral'` | <br/> `'deepseek'` | <br/> `'gemini'` | <br/> `'ollama'` | <br/> `'openrouter'` | <br/> `'alibaba'` | <br/> `'fireworks'` | <br/> `'groq'` | <br/> `'huggingface'` | <br/> `'bedrock'` | <br/> `'googleaistudio'` | <br/> `'googlevertex'` | <br/> `'togetherai'` | <br/> `'lmstudio'` | `undefined` | `'anthropic'` | Diferentes proveedores requieren diferentes llaves de API y tienen distintos precios. |
|
|
929
|
+
| `model` | El modelo que se usará para las funciones de IA. | `string` | Ninguno | `'gpt-4o-2024-11-20'` | El modelo específico varía según el proveedor. |
|
|
930
|
+
| `temperature` | Controla la aleatoriedad de las respuestas de la IA. | `number` | Ninguno | `0.1` | Temperatura más alta = más creativo y menos predecible. |
|
|
931
|
+
| `apiKey` | Su llave API para el proveedor seleccionado. | `string` | Ninguno | `process.env.OPENAI_API_KEY` | Manténgalo en secreto; almacénelo en variables de entorno. |
|
|
932
|
+
| `applicationContext` | Contexto adicional sobre su aplicación para ayudar a la IA a generar traducciones más precisas (dominio, audiencia, tono, terminología). | `string` | Ninguno | `'Mi contexto de aplicación'` | Puede usarse para añadir reglas (p. ej.: `"No debes transformar las urls"`). |
|
|
933
|
+
| `baseURL` | La URL base para la API de IA. | `string` | Ninguno | `'https://api.openai.com/v1'` <br/> `'http://localhost:5000'` | Puede apuntar a un endpoint de API de IA local o personalizado. |
|
|
934
|
+
| `dataSerialization` | Formato de serialización de datos para las funciones de IA. | `'json'` | <br/> `'toon'` | `undefined` | `'toon'` | • `'json'`: estándar, fiable; usa más tokens.<br/>• `'toon'`: menos tokens, menos consistente.<br/>• Se pasan parámetros adicionales al modelo como contexto (esfuerzo de razonamiento, etc.). |
|
|
931
935
|
|
|
932
936
|
---
|
|
933
937
|
|