@intlayer/docs 9.5.7 → 9.5.8
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/blog/ar/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/de/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/en/is_intlayer_lighter_than_paraglide.md +288 -0
- package/blog/en-GB/is_intlayer_lighter_than_paraglide.md +285 -0
- package/blog/es/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/fr/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/hi/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/id/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/it/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ja/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ko/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/pl/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/pt/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ru/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/tr/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/uk/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/vi/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/zh/is_intlayer_lighter_than_paraglide.md +284 -0
- package/dist/cjs/generated/blog.entry.cjs +20 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/index.cjs +2 -2
- package/dist/esm/generated/blog.entry.mjs +20 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/index.mjs +2 -2
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/nextjs.md +6 -3
- package/docs/ar/benchmark/solid.md +21 -4
- package/docs/ar/benchmark/svelte.md +18 -3
- package/docs/ar/benchmark/tanstack.md +6 -3
- package/docs/ar/benchmark/vue.md +14 -5
- package/docs/ar/cli/index.md +6 -1
- package/docs/ar/cli/upgrade.md +125 -0
- package/docs/de/benchmark/nextjs.md +6 -3
- package/docs/de/benchmark/solid.md +21 -4
- package/docs/de/benchmark/svelte.md +18 -3
- package/docs/de/benchmark/tanstack.md +6 -3
- package/docs/de/benchmark/vue.md +14 -5
- package/docs/de/cli/index.md +6 -1
- package/docs/de/cli/upgrade.md +125 -0
- package/docs/en/agent_skills.md +29 -1
- package/docs/en/benchmark/nextjs.md +6 -3
- package/docs/en/benchmark/solid.md +21 -4
- package/docs/en/benchmark/svelte.md +18 -3
- package/docs/en/benchmark/tanstack.md +7 -4
- package/docs/en/benchmark/vue.md +15 -6
- package/docs/en/cli/index.md +6 -1
- package/docs/en/cli/upgrade.md +125 -0
- package/docs/en-GB/benchmark/nextjs.md +6 -3
- package/docs/en-GB/benchmark/solid.md +21 -4
- package/docs/en-GB/benchmark/svelte.md +18 -3
- package/docs/en-GB/benchmark/tanstack.md +6 -3
- package/docs/en-GB/benchmark/vue.md +15 -6
- package/docs/en-GB/cli/index.md +6 -1
- package/docs/en-GB/cli/upgrade.md +125 -0
- package/docs/es/benchmark/nextjs.md +6 -3
- package/docs/es/benchmark/solid.md +21 -4
- package/docs/es/benchmark/svelte.md +18 -3
- package/docs/es/benchmark/tanstack.md +6 -3
- package/docs/es/benchmark/vue.md +14 -5
- package/docs/es/cli/index.md +6 -1
- package/docs/es/cli/upgrade.md +125 -0
- package/docs/fr/benchmark/nextjs.md +6 -3
- package/docs/fr/benchmark/solid.md +21 -4
- package/docs/fr/benchmark/svelte.md +18 -3
- package/docs/fr/benchmark/tanstack.md +6 -3
- package/docs/fr/benchmark/vue.md +15 -6
- package/docs/fr/cli/index.md +6 -1
- package/docs/fr/cli/upgrade.md +125 -0
- package/docs/hi/benchmark/nextjs.md +6 -3
- package/docs/hi/benchmark/solid.md +21 -4
- package/docs/hi/benchmark/svelte.md +18 -3
- package/docs/hi/benchmark/tanstack.md +6 -3
- package/docs/hi/benchmark/vue.md +15 -6
- package/docs/hi/cli/index.md +6 -1
- package/docs/hi/cli/upgrade.md +125 -0
- package/docs/id/benchmark/nextjs.md +6 -3
- package/docs/id/benchmark/solid.md +21 -4
- package/docs/id/benchmark/svelte.md +18 -3
- package/docs/id/benchmark/tanstack.md +6 -3
- package/docs/id/benchmark/vue.md +15 -6
- package/docs/id/cli/index.md +6 -1
- package/docs/id/cli/upgrade.md +125 -0
- package/docs/it/benchmark/nextjs.md +6 -3
- package/docs/it/benchmark/solid.md +21 -4
- package/docs/it/benchmark/svelte.md +18 -3
- package/docs/it/benchmark/tanstack.md +6 -3
- package/docs/it/benchmark/vue.md +14 -5
- package/docs/it/cli/index.md +6 -1
- package/docs/it/cli/upgrade.md +125 -0
- package/docs/ja/benchmark/nextjs.md +6 -3
- package/docs/ja/benchmark/solid.md +21 -4
- package/docs/ja/benchmark/svelte.md +18 -3
- package/docs/ja/benchmark/tanstack.md +5 -2
- package/docs/ja/benchmark/vue.md +14 -5
- package/docs/ja/cli/index.md +6 -1
- package/docs/ja/cli/upgrade.md +125 -0
- package/docs/ko/benchmark/nextjs.md +6 -3
- package/docs/ko/benchmark/solid.md +21 -4
- package/docs/ko/benchmark/svelte.md +18 -3
- package/docs/ko/benchmark/tanstack.md +6 -3
- package/docs/ko/benchmark/vue.md +15 -6
- package/docs/ko/cli/index.md +6 -1
- package/docs/ko/cli/upgrade.md +126 -0
- package/docs/pl/benchmark/nextjs.md +6 -3
- package/docs/pl/benchmark/solid.md +21 -4
- package/docs/pl/benchmark/svelte.md +18 -3
- package/docs/pl/benchmark/tanstack.md +6 -3
- package/docs/pl/benchmark/vue.md +15 -6
- package/docs/pl/cli/index.md +6 -1
- package/docs/pl/cli/upgrade.md +125 -0
- package/docs/pt/benchmark/nextjs.md +6 -3
- package/docs/pt/benchmark/solid.md +21 -4
- package/docs/pt/benchmark/svelte.md +18 -3
- package/docs/pt/benchmark/tanstack.md +6 -3
- package/docs/pt/benchmark/vue.md +14 -5
- package/docs/pt/cli/index.md +6 -1
- package/docs/pt/cli/upgrade.md +125 -0
- package/docs/ru/benchmark/nextjs.md +6 -3
- package/docs/ru/benchmark/solid.md +21 -4
- package/docs/ru/benchmark/svelte.md +18 -3
- package/docs/ru/benchmark/tanstack.md +6 -3
- package/docs/ru/benchmark/vue.md +15 -6
- package/docs/ru/cli/index.md +6 -1
- package/docs/ru/cli/upgrade.md +125 -0
- package/docs/tr/benchmark/nextjs.md +6 -3
- package/docs/tr/benchmark/solid.md +21 -4
- package/docs/tr/benchmark/svelte.md +18 -3
- package/docs/tr/benchmark/tanstack.md +6 -3
- package/docs/tr/benchmark/vue.md +15 -6
- package/docs/tr/cli/index.md +6 -1
- package/docs/tr/cli/upgrade.md +125 -0
- package/docs/uk/benchmark/nextjs.md +6 -3
- package/docs/uk/benchmark/solid.md +21 -4
- package/docs/uk/benchmark/svelte.md +18 -3
- package/docs/uk/benchmark/tanstack.md +6 -3
- package/docs/uk/benchmark/vue.md +15 -6
- package/docs/uk/cli/index.md +6 -1
- package/docs/uk/cli/upgrade.md +125 -0
- package/docs/vi/benchmark/nextjs.md +6 -3
- package/docs/vi/benchmark/solid.md +21 -4
- package/docs/vi/benchmark/svelte.md +18 -3
- package/docs/vi/benchmark/tanstack.md +6 -3
- package/docs/vi/benchmark/vue.md +15 -6
- package/docs/vi/cli/index.md +6 -1
- package/docs/vi/cli/upgrade.md +125 -0
- package/docs/zh/benchmark/nextjs.md +6 -3
- package/docs/zh/benchmark/solid.md +21 -4
- package/docs/zh/benchmark/svelte.md +18 -3
- package/docs/zh/benchmark/tanstack.md +5 -2
- package/docs/zh/benchmark/vue.md +15 -6
- package/docs/zh/cli/index.md +6 -1
- package/docs/zh/cli/upgrade.md +125 -0
- package/package.json +6 -6
- package/src/generated/blog.entry.ts +20 -0
- package/src/generated/docs.entry.ts +20 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-23
|
|
3
|
+
updatedAt: 2026-09-23
|
|
4
|
+
title: Intlayer è più leggero di Paraglide?
|
|
5
|
+
description: Paraglide sembra quasi gratuito nei benchmark i18n perché il suo codice viene generato nel tuo repository. Ecco dove finisce realmente quel peso, perché la risoluzione della locale per nodo costa e come il caricamento dinamico di Intlayer invia una sola lingua anziché tutte.
|
|
6
|
+
keywords:
|
|
7
|
+
- Paraglide
|
|
8
|
+
- Intlayer
|
|
9
|
+
- Internazionalizzazione
|
|
10
|
+
- i18n
|
|
11
|
+
- Bundle size
|
|
12
|
+
- Tree shaking
|
|
13
|
+
- Benchmark
|
|
14
|
+
- Blog
|
|
15
|
+
slugs:
|
|
16
|
+
- blog
|
|
17
|
+
- is-intlayer-lighter-than-paraglide
|
|
18
|
+
author: aymericzip
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Intlayer è più leggero di Paraglide?
|
|
22
|
+
|
|
23
|
+
Sì.
|
|
24
|
+
|
|
25
|
+
`Paraglide` ha la reputazione di essere la soluzione i18n più leggera in circolazione, e a prima vista il [benchmark](https://intlayer.org/it/doc/benchmark/tanstack) sembra confermarlo: la dimensione della sua libreria è vicina allo zero. Tuttavia, una dimensione della libreria pari a zero non significa zero byte inviati. Significa solo che i byte si trovano dove la metrica non va a guardare.
|
|
26
|
+
|
|
27
|
+
<TOC/>
|
|
28
|
+
|
|
29
|
+
## Punti chiave
|
|
30
|
+
|
|
31
|
+
**La dimensione della libreria è nascosta, non eliminata:**
|
|
32
|
+
|
|
33
|
+
Paraglide genera il suo runtime e le funzioni dei messaggi direttamente nella tua codebase. Quel codice viene inviato al browser, ma viene conteggiato come _tuo_ codice, non come codice della libreria.
|
|
34
|
+
|
|
35
|
+
**Nessun provider non significa un vantaggio gratuito:**
|
|
36
|
+
|
|
37
|
+
Ogni chiamata a `m.my_key()` risolve la locale in autonomia, leggendo il cookie o lo storage per ciascun nodo renderizzato, invece di leggerlo una sola volta da un contesto.
|
|
38
|
+
|
|
39
|
+
**Nessun caricamento dinamico:**
|
|
40
|
+
|
|
41
|
+
Paraglide importa ogni locale di un messaggio nel bundle client. Intlayer con `importMode: 'dynamic'` o `'fetch'` carica solo la lingua effettivamente renderizzata.
|
|
42
|
+
|
|
43
|
+
**Il tree shaking non è garantito:**
|
|
44
|
+
|
|
45
|
+
In alcuni dei nostri benchmark, il tree shaking promesso da Paraglide non ha avuto effetto. Verifica il tuo stesso bundle.
|
|
46
|
+
|
|
47
|
+
## Dove finisce il peso di Paraglide?
|
|
48
|
+
|
|
49
|
+
Nei report di benchmark, la metrica "dimensione della libreria" misura il provider e gli hook di ciascuna libreria i18n in un componente vuoto, prima che venga aggiunto qualsiasi contenuto.
|
|
50
|
+
|
|
51
|
+
| Libreria (TanStack Start) | Dimensione lib (gz) | Dimensione lib (min) |
|
|
52
|
+
| ----------------------------- | ------------------- | -------------------- |
|
|
53
|
+
| `@inlang/paraglide-js@2.15.1` | 1.8 KB | 4.5 KB |
|
|
54
|
+
| `react-intlayer@9.5.1` | 5.0 KB | 15.2 KB |
|
|
55
|
+
|
|
56
|
+
Letto in isolamento, Paraglide vince. Ma Paraglide è un compilatore: legge i tuoi file `messages/*.json` e scrive una cartella `paraglide/` nel tuo repository, contenente un file `runtime.js` (rilevamento della locale, strategie per cookie e storage, localizzazione degli URL) e una funzione JavaScript per ciascun messaggio.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
src/paraglide/
|
|
60
|
+
├── runtime.js # rilevamento locale, strategie, helper per URL
|
|
61
|
+
├── server.js
|
|
62
|
+
├── messages.js # riesporta ogni messaggio
|
|
63
|
+
└── messages/
|
|
64
|
+
├── _index.js
|
|
65
|
+
├── en.js
|
|
66
|
+
└── fr.js
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Poiché questo codice si trova nella tua cartella `src/` e lo importi con un percorso relativo, il bundler lo attribuisce alla tua applicazione e non a un pacchetto in `node_modules`. La colonna della dimensione della libreria mostra quasi nulla, mentre la stessa logica viene comunque inclusa nel bundle della tua pagina.
|
|
70
|
+
|
|
71
|
+
Generare codice non è un'idea sbagliata in sé: il runtime generato include solo la logica richiesta dalla tua configurazione (strategia di prefisso, cookie vs. local storage, ecc.). Intlayer ottiene lo stesso risultato in modo diverso, iniettando variabili d'ambiente in fase di build in modo che il bundler elimini i rami che la tua configurazione non utilizza. Entrambi gli approcci risultano da 3 a 10 volte più leggeri rispetto a `i18next` o `next-intl`.
|
|
72
|
+
|
|
73
|
+
Il confronto equo non riguarda quindi la dimensione della libreria. Riguarda **il JavaScript effettivamente inviato per pagina**.
|
|
74
|
+
|
|
75
|
+
## Peso per pagina, misurato
|
|
76
|
+
|
|
77
|
+
Applicazione TanStack Start, 10 pagine, misurata sulle route `en` e `fr`, compressa con gzip:
|
|
78
|
+
|
|
79
|
+
| Configurazione | Media JS pag (gz) | Sopra la base | Perdita di locale | Perdita altre pagine |
|
|
80
|
+
| ---------------------------------- | ----------------- | ------------- | ----------------- | -------------------- |
|
|
81
|
+
| Base (senza i18n) | 111.0 KB | - | 0.0% | 0.0% |
|
|
82
|
+
| `paraglide` (qualsiasi strategia) | 125.1 KB | +14.1 KB | 49.7% | 0.0% |
|
|
83
|
+
| `intlayer` (`importMode: static`) | 125.8 KB | +14.8 KB | 50.0% | 0.0% |
|
|
84
|
+
| `intlayer` (`importMode: dynamic`) | **118.6 KB** | **+7.6 KB** | **0.0%** | **0.0%** |
|
|
85
|
+
|
|
86
|
+
Next.js 16 App Router, stessa applicazione:
|
|
87
|
+
|
|
88
|
+
| Configurazione | Media JS pag (gz) | Sopra la base |
|
|
89
|
+
| ----------------- | ----------------- | ------------- |
|
|
90
|
+
| Base (senza i18n) | 141.0 KB | - |
|
|
91
|
+
| `paraglide-next` | 155.3 KB | +14.3 KB |
|
|
92
|
+
| `next-intlayer` | **141.3 KB** | **+0.3 KB** |
|
|
93
|
+
|
|
94
|
+
<I18nBenchmark framework="tanstack" vertical/>
|
|
95
|
+
|
|
96
|
+
> Dati completi nel [report di benchmark TanStack Start](https://intlayer.org/it/doc/benchmark/tanstack) e nel [report di benchmark Next.js](https://intlayer.org/it/doc/benchmark/nextjs). Ogni bundle può essere ispezionato nel [repository del benchmark](https://github.com/intlayer-org/benchmark-i18n).
|
|
97
|
+
|
|
98
|
+
Due aspetti emergono con evidenza:
|
|
99
|
+
|
|
100
|
+
- In modalità `static`, Intlayer invia praticamente lo stesso contenuto di Paraglide (125.8 KB contro 125.1 KB). È quanto ci si aspetta: entrambi includono tutte le lingue dei messaggi utilizzati da una pagina.
|
|
101
|
+
- Paraglide rimane a 125.1 KB con qualsiasi strategia, poiché è privo di una modalità dinamica. Ogni riga nella tabella precedente corrisponde alla variante statica.
|
|
102
|
+
|
|
103
|
+
## Nessun Provider: un'idea all'apparenza ottima che non lo è
|
|
104
|
+
|
|
105
|
+
Paraglide non necessita di provider. Si importa un messaggio e lo si invoca:
|
|
106
|
+
|
|
107
|
+
```tsx fileName="Hero.tsx"
|
|
108
|
+
import { m } from "../paraglide/messages.js";
|
|
109
|
+
|
|
110
|
+
export const Hero = () => (
|
|
111
|
+
<section>
|
|
112
|
+
<h1>{m.hero_title()}</h1>
|
|
113
|
+
<p>{m.hero_description()}</p>
|
|
114
|
+
<button>{m.hero_cta()}</button>
|
|
115
|
+
</section>
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Nessun contesto, nessun wrapper, nessun hook. Sembra più semplice. Ma la locale deve pur essere ricavata da qualche parte. Ogni funzione di messaggio generata assomiglia grossomodo a questo (versione semplificata):
|
|
120
|
+
|
|
121
|
+
```js fileName="paraglide/messages/_index.js"
|
|
122
|
+
export const hero_title = (inputs = {}, options = {}) => {
|
|
123
|
+
const locale = options.locale ?? getLocale(); // risolto a ogni invocazione
|
|
124
|
+
|
|
125
|
+
if (locale === "en") return en.hero_title(inputs);
|
|
126
|
+
if (locale === "fr") return fr.hero_title(inputs);
|
|
127
|
+
// ...un ramo per ogni locale
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
E `getLocale()` scansiona le strategie configurate (cookie, local storage, URL, locale di base) per trovare la locale attiva. Pertanto, ogni nodo di testo renderizzato (`<>{m.my_key()}</>`) esegue la propria risoluzione della lingua, inclusa la lettura di `document.cookie` nel browser. Una pagina con 200 stringhe tradotte risolve la locale 200 volte per render, e di nuovo a ogni re-render.
|
|
132
|
+
|
|
133
|
+
Una libreria basata su provider legge la lingua **una sola volta**, la memorizza in un contesto (o in un segnale, o in uno store), e ogni nodo legge un valore già presente in memoria. Il provider costa poche centinaia di byte. Eliminarlo consuma cicli di CPU a ogni render, come dimostrato nel benchmark: i tempi di caricamento pagina e di cambio lingua di Paraglide sono costantemente inferiori rispetto a quelli di Intlayer su TanStack Start (22.1 ms contro 14.6 ms nel caricamento pagina, 4.3 ms contro 3.2 ms nella reattività E2E).
|
|
134
|
+
|
|
135
|
+
## Esperienza di sviluppo (DX)
|
|
136
|
+
|
|
137
|
+
La fonte di verità di Paraglide è il formato JSON, ma non si importa mai il file JSON direttamente. Si importa il file `.js` generato:
|
|
138
|
+
|
|
139
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
140
|
+
<Tab label="Paraglide" value="paraglide">
|
|
141
|
+
|
|
142
|
+
```json fileName="messages/en.json"
|
|
143
|
+
{
|
|
144
|
+
"hero_title": "Ship your app in every language"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```json fileName="messages/it.json"
|
|
149
|
+
{
|
|
150
|
+
"hero_title": "Pubblica la tua app in ogni lingua"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx fileName="Hero.tsx"
|
|
155
|
+
// Esiste solo dopo che il compilatore lo ha rigenerato a partire dal JSON
|
|
156
|
+
import { m } from "../paraglide/messages.js";
|
|
157
|
+
|
|
158
|
+
export const Hero = () => <h1>{m.hero_title()}</h1>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
</Tab>
|
|
162
|
+
<Tab label="Intlayer" value="intlayer">
|
|
163
|
+
|
|
164
|
+
```ts fileName="Hero.content.ts"
|
|
165
|
+
import { t, type Dictionary } from "intlayer";
|
|
166
|
+
|
|
167
|
+
export default {
|
|
168
|
+
key: "hero",
|
|
169
|
+
content: {
|
|
170
|
+
title: t({
|
|
171
|
+
it: "Pubblica la tua app in ogni lingua",
|
|
172
|
+
en: "Ship your app in every language",
|
|
173
|
+
}),
|
|
174
|
+
},
|
|
175
|
+
} satisfies Dictionary;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```tsx fileName="Hero.tsx"
|
|
179
|
+
import { useIntlayer } from "react-intlayer";
|
|
180
|
+
|
|
181
|
+
export const Hero = () => {
|
|
182
|
+
const { title } = useIntlayer("hero");
|
|
183
|
+
|
|
184
|
+
return <h1>{title}</h1>;
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
</Tab>
|
|
189
|
+
</Tabs>
|
|
190
|
+
|
|
191
|
+
Questo ciclo di lavoro comporta dei compromessi:
|
|
192
|
+
|
|
193
|
+
- Ogni modifica a un file JSON richiede una rigenerazione prima che l'importazione si risolva o che i tipi vengano aggiornati.
|
|
194
|
+
- La cartella generata `paraglide/` deve essere inclusa nel repository (generando conflitti di merge sui file generati in ogni PR che modifica testi) oppure ignorata (richiedendo un passaggio di generazione prima di ogni type check, test e job di CI).
|
|
195
|
+
- Ogni stringa diventa una chiamata a funzione. Le costanti diventano ovunque `m.key()`, anche nei punti in cui basterebbe un valore statico.
|
|
196
|
+
|
|
197
|
+
## Tree Shaking: verifica il tuo bundle
|
|
198
|
+
|
|
199
|
+
La promessa fondamentale di Paraglide è che i messaggi non utilizzati vengono eliminati tramite tree shaking, poiché ogni messaggio rappresenta un export separato. Nel benchmark Svelte + Vite, questo funziona come pubblicizzato.
|
|
200
|
+
|
|
201
|
+
In altri contesti, non è stato così. Nel nostro test su [Next.js](https://intlayer.org/it/doc/benchmark/nextjs), le pagine di Paraglide pesano 14 KB in più rispetto all'applicazione di base, mentre `next-intlayer` aggiunge solo 0.3 KB. Test precedenti su TanStack Start hanno mostrato che anche i messaggi di altre pagine finivano nel bundle della route.
|
|
202
|
+
|
|
203
|
+
Il tree shaking dipende dal tuo bundler (Turbopack, Rolldown, Rollup), da come vengono importati i messaggi (`import { m }` vs. `import * as m`) e dall'analisi dei side effect. Se scegli Paraglide per le sue dimensioni ridotte, apri il visualizzatore del bundle e controlla che tali promesse si mantengano nella tua applicazione.
|
|
204
|
+
|
|
205
|
+
## Nessun caricamento dinamico
|
|
206
|
+
|
|
207
|
+
Questo è il limite strutturale. Paraglide non prevede un meccanismo per caricare una sola lingua alla volta: ogni funzione di messaggio importa staticamente l'implementazione di ciascuna lingua, cosicché tutte le lingue finiscono nel bundle inviato al client.
|
|
208
|
+
|
|
209
|
+
Con 2 lingue, metà del payload delle traduzioni viene sprecato, in linea con il ~50% di perdita di locale misurato in precedenza. Con 10 lingue, il 90%. Con 30 lingue, il 97%.
|
|
210
|
+
|
|
211
|
+
Passare al caricamento dinamico non risolverebbe il problema: disponendo di una funzione per ciascun messaggio, caricare ogni funzione in modalità lazy comporterebbe migliaia di richieste di rete.
|
|
212
|
+
|
|
213
|
+
Intlayer consente di scegliere la strategia, a livello globale o per dizionario:
|
|
214
|
+
|
|
215
|
+
```ts fileName="intlayer.config.ts"
|
|
216
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
217
|
+
|
|
218
|
+
const config: IntlayerConfig = {
|
|
219
|
+
internationalization: {
|
|
220
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
221
|
+
defaultLocale: Locales.ENGLISH,
|
|
222
|
+
},
|
|
223
|
+
dictionary: {
|
|
224
|
+
importMode: "dynamic", // 'static' | 'dynamic' | 'fetch'
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export default config;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
| `importMode` | Cosa viene inviato al client | vs. Paraglide |
|
|
232
|
+
| ------------ | ---------------------------------------------------------- | ------------------------------------ |
|
|
233
|
+
| `static` | Tutte le lingue dei dizionari utilizzati dalla pagina | Teoricamente lo stesso contenuto |
|
|
234
|
+
| `dynamic` | Solo la lingua attiva, caricata on demand per dizionario | **N volte più leggero** con N lingue |
|
|
235
|
+
| `fetch` | Solo la lingua attiva, recuperata tramite la Live Sync API | **N volte più leggero** con N lingue |
|
|
236
|
+
|
|
237
|
+
Grazie alla [trasformazione in fase di build](https://intlayer.org/it/doc/concept/bundle-optimization) e alla modalità `importMode: 'static'`, Intlayer carica, in teoria, esattamente lo stesso contenuto di Paraglide. Con `'dynamic'` o `'fetch'`, carica solo ciò che la lingua corrente richiede: per un'applicazione in N lingue, il payload delle traduzioni è N volte inferiore rispetto a Paraglide.
|
|
238
|
+
|
|
239
|
+
## Quando Paraglide è ancora adatto
|
|
240
|
+
|
|
241
|
+
<AccordionGroup>
|
|
242
|
+
<Accordion header="Svelte + Vite con poche lingue">
|
|
243
|
+
|
|
244
|
+
Se il tuo stack è Svelte con Vite e supporti due o tre lingue, il tree shaking funziona come promesso e il sovraccarico delle lingue rimane minimo.
|
|
245
|
+
|
|
246
|
+
</Accordion>
|
|
247
|
+
<Accordion header="Workflow inlang esistente">
|
|
248
|
+
|
|
249
|
+
Se il tuo team utilizza già l'ecosistema inlang (Fink, Sherlock, plugin per i formati dei messaggi), Paraglide vi si integra in modo nativo.
|
|
250
|
+
|
|
251
|
+
</Accordion>
|
|
252
|
+
</AccordionGroup>
|
|
253
|
+
|
|
254
|
+
## Provalo sulla tua applicazione
|
|
255
|
+
|
|
256
|
+
Verifica il payload e le perdite di locale della tua applicazione in produzione con l'[i18n SEO Scanner](https://intlayer.org/i18n-seo-scanner) gratuito:
|
|
257
|
+
|
|
258
|
+
<ClickToOpenIframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
259
|
+
|
|
260
|
+
Per configurare Intlayer:
|
|
261
|
+
|
|
262
|
+
```bash packageManager="npm"
|
|
263
|
+
npx intlayer init --interactive
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash packageManager="pnpm"
|
|
267
|
+
pnpm dlx intlayer init --interactive
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```bash packageManager="yarn"
|
|
271
|
+
yarn dlx intlayer init --interactive
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
```bash packageManager="bun"
|
|
275
|
+
bunx intlayer init --interactive
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Ulteriori letture
|
|
279
|
+
|
|
280
|
+
- [Benchmark i18n TanStack Start](https://intlayer.org/it/doc/benchmark/tanstack)
|
|
281
|
+
- [Benchmark i18n Next.js](https://intlayer.org/it/doc/benchmark/nextjs)
|
|
282
|
+
- [Ottimizzazione del bundle e `importMode`](https://intlayer.org/it/doc/concept/bundle-optimization)
|
|
283
|
+
- [Come scegliere una libreria i18n per React](https://intlayer.org/it/blog/how-to-pick-react-i18n-library)
|
|
284
|
+
- [Perché scegliere l'internazionalizzazione guidata da compilatore](https://intlayer.org/it/blog/compiler-vs-declarative-i18n)
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-23
|
|
3
|
+
updatedAt: 2026-09-23
|
|
4
|
+
title: Intlayer は Paraglide より軽い?
|
|
5
|
+
description: Paraglide はコードがリポジトリ内に直接生成されるため、i18n ベンチマークではほぼノーコストのように見えます。その容量が実際にはどこに移動しているのか、ノードごとのロケール読み取りがなぜコストになるのか、そして Intlayer の動的読み込みが全言語ではなく必要なロケールのみを配信する仕組みを解説します。
|
|
6
|
+
keywords:
|
|
7
|
+
- Paraglide
|
|
8
|
+
- Intlayer
|
|
9
|
+
- 国際化
|
|
10
|
+
- i18n
|
|
11
|
+
- Bundle size
|
|
12
|
+
- Tree shaking
|
|
13
|
+
- Benchmark
|
|
14
|
+
- Blog
|
|
15
|
+
slugs:
|
|
16
|
+
- blog
|
|
17
|
+
- is-intlayer-lighter-than-paraglide
|
|
18
|
+
author: aymericzip
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Intlayer は Paraglide より軽い?
|
|
22
|
+
|
|
23
|
+
結論から言うと、軽いです。
|
|
24
|
+
|
|
25
|
+
`Paraglide` は極めて軽量な i18n ソリューションとして知られており、一見すると [ベンチマーク](https://intlayer.org/ja/doc/benchmark/tanstack) でもそれが裏付けられているように見えます。ライブラリサイズはほぼゼロです。しかし、ライブラリサイズがゼロであることは、配信されるバイト数がゼロであることを意味しません。その指標がカウントしていない別の場所にバイトが隠れているに過ぎません。
|
|
26
|
+
|
|
27
|
+
<TOC/>
|
|
28
|
+
|
|
29
|
+
## 主なポイント
|
|
30
|
+
|
|
31
|
+
**ライブラリサイズは消えたのではなく、隠されているだけ:**
|
|
32
|
+
|
|
33
|
+
Paraglide はランタイムとメッセージ関数をご自身のコードベース内に生成します。そのコードはブラウザに送信されますが、ライブラリではなく「あなた自身のコード」としてカウントされます。
|
|
34
|
+
|
|
35
|
+
**Provider なしは無料の勝利ではない:**
|
|
36
|
+
|
|
37
|
+
`m.my_key()` の呼び出しごとにロケールを個別に解決し、レンダリングされるノードごとに Cookie やストレージを読み取ります。コンテキストから一度だけ読み取る方式ではありません。
|
|
38
|
+
|
|
39
|
+
**動的読み込み(Dynamic Loading)に対応していない:**
|
|
40
|
+
|
|
41
|
+
Paraglide はメッセージのすべての言語をクライアントバンドルにインポートします。Intlayer で `importMode: 'dynamic'` または `'fetch'` を使用すると、現在表示されているロケールのみが読み込まれます。
|
|
42
|
+
|
|
43
|
+
**Tree Shaking は保証されない:**
|
|
44
|
+
|
|
45
|
+
いくつかのベンチマーク環境では、Paraglide がアピールする Tree Shaking が機能しませんでした。ご自身のバンドルで検証することをおすすめします。
|
|
46
|
+
|
|
47
|
+
## Paraglide の容量はどこへ消えたのか?
|
|
48
|
+
|
|
49
|
+
ベンチマークレポートの「ライブラリサイズ」指標は、コンテンツを追加する前の空のコンポーネントにおける各 i18n ライブラリの Provider とフックのサイズを測定しています。
|
|
50
|
+
|
|
51
|
+
| ライブラリ (TanStack Start) | ライブラリサイズ (gz) | ライブラリサイズ (min) |
|
|
52
|
+
| ----------------------------- | --------------------- | ---------------------- |
|
|
53
|
+
| `@inlang/paraglide-js@2.15.1` | 1.8 KB | 4.5 KB |
|
|
54
|
+
| `react-intlayer@9.5.1` | 5.0 KB | 15.2 KB |
|
|
55
|
+
|
|
56
|
+
この数値だけを切り取れば Paraglide の勝ちに見えます。しかし Paraglide はコンパイラです。`messages/*.json` ファイルを読み込み、リポジトリ内に `paraglide/` フォルダを生成します。その中には `runtime.js`(ロケール検出、Cookie やストレージ戦略、URL ローカライズ)と、メッセージごとの JavaScript 関数が出力されます。
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
src/paraglide/
|
|
60
|
+
├── runtime.js # ロケール検出、各種戦略、URL ヘルパー
|
|
61
|
+
├── server.js
|
|
62
|
+
├── messages.js # 全メッセージの再エクスポート
|
|
63
|
+
└── messages/
|
|
64
|
+
├── _index.js
|
|
65
|
+
├── en.js
|
|
66
|
+
└── fr.js
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
このコードは `src/` フォルダ内に配置され相対パスでインポートされるため、バンドラーはこれを `node_modules` のパッケージではなく、アプリケーション自身のコードとして分類します。そのため、ライブラリサイズの列にはほとんど何も表示されませんが、ページバンドル内には全く同じロジックが配信されています。
|
|
70
|
+
|
|
71
|
+
コードを生成すること自体は悪いアイデアではありません。生成されたランタイムには、設定で必要とされたロジック(プレフィックス戦略、Cookie vs ローカルストレージなど)のみが含まれます。Intlayer は異なるアプローチで同じ成果を実現しています。ビルド時に環境変数を注入することで、バンドラーが設定で使用されていない分岐を自動的に削除します。どちらのアプローチも、`i18next` や `next-intl` と比べて 3〜10 倍軽量です。
|
|
72
|
+
|
|
73
|
+
したがって、公平な比較の基準はライブラリサイズではありません。**ページごとに実際に送信される JavaScript の総量**です。
|
|
74
|
+
|
|
75
|
+
## 実測されたページ容量
|
|
76
|
+
|
|
77
|
+
TanStack Start アプリケーション、10 ページ構成、`en` および `fr` ルートで計測(gzip 圧縮):
|
|
78
|
+
|
|
79
|
+
| 構成 | ページ JS 平均 (gz) | ベース比 | ロケール漏洩率 | 他ページ漏洩率 |
|
|
80
|
+
| ---------------------------------- | ------------------- | ----------- | -------------- | -------------- |
|
|
81
|
+
| ベース (i18n なし) | 111.0 KB | - | 0.0% | 0.0% |
|
|
82
|
+
| `paraglide` (すべての戦略) | 125.1 KB | +14.1 KB | 49.7% | 0.0% |
|
|
83
|
+
| `intlayer` (`importMode: static`) | 125.8 KB | +14.8 KB | 50.0% | 0.0% |
|
|
84
|
+
| `intlayer` (`importMode: dynamic`) | **118.6 KB** | **+7.6 KB** | **0.0%** | **0.0%** |
|
|
85
|
+
|
|
86
|
+
Next.js 16 App Router、同一アプリケーション:
|
|
87
|
+
|
|
88
|
+
| 構成 | ページ JS 平均 (gz) | ベース比 |
|
|
89
|
+
| ------------------ | ------------------- | ----------- |
|
|
90
|
+
| ベース (i18n なし) | 141.0 KB | - |
|
|
91
|
+
| `paraglide-next` | 155.3 KB | +14.3 KB |
|
|
92
|
+
| `next-intlayer` | **141.3 KB** | **+0.3 KB** |
|
|
93
|
+
|
|
94
|
+
<I18nBenchmark framework="tanstack" vertical/>
|
|
95
|
+
|
|
96
|
+
> 詳細なデータは [TanStack Start ベンチマークレポート](https://intlayer.org/ja/doc/benchmark/tanstack) および [Next.js ベンチマークレポート](https://intlayer.org/ja/doc/benchmark/nextjs) を参照してください。すべてのバンドルは [ベンチマークリポジトリ](https://github.com/intlayer-org/benchmark-i18n) で確認できます。
|
|
97
|
+
|
|
98
|
+
2 つの重要な事実が浮き彫りになります:
|
|
99
|
+
|
|
100
|
+
- `static` モードにおいて、Intlayer は Paraglide とほぼ同じサイズのコンテンツを配信します(125.8 KB vs 125.1 KB)。これは当然です。どちらもページが使用するメッセージの全言語を含んでいるからです。
|
|
101
|
+
- Paraglide は動的モードを持たないため、どのような戦略を選択しても 125.1 KB のままです。上記の表の各行は静的読み込みに相当します。
|
|
102
|
+
|
|
103
|
+
## Provider なし:一見良さそうで実はそうではない設計
|
|
104
|
+
|
|
105
|
+
Paraglide には Provider がありません。メッセージをインポートして呼び出すだけです:
|
|
106
|
+
|
|
107
|
+
```tsx fileName="Hero.tsx"
|
|
108
|
+
import { m } from "../paraglide/messages.js";
|
|
109
|
+
|
|
110
|
+
export const Hero = () => (
|
|
111
|
+
<section>
|
|
112
|
+
<h1>{m.hero_title()}</h1>
|
|
113
|
+
<p>{m.hero_description()}</p>
|
|
114
|
+
<button>{m.hero_cta()}</button>
|
|
115
|
+
</section>
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
コンテキストも、ラッパーも、フックもありません。シンプルに見えます。しかし、ロケール情報はどこかから取得する必要があります。生成される各メッセージ関数は、大まかに以下のようになっています(簡略化版):
|
|
120
|
+
|
|
121
|
+
```js fileName="paraglide/messages/_index.js"
|
|
122
|
+
export const hero_title = (inputs = {}, options = {}) => {
|
|
123
|
+
const locale = options.locale ?? getLocale(); // 呼び出しごとに毎回解決される
|
|
124
|
+
|
|
125
|
+
if (locale === "en") return en.hero_title(inputs);
|
|
126
|
+
if (locale === "fr") return fr.hero_title(inputs);
|
|
127
|
+
// ...言語ごとの分岐
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
そして `getLocale()` は設定された戦略(Cookie、ローカルストレージ、URL、ベースロケール)を走査して現在のロケールを探します。つまり、描画する各テキストノード(`<>{m.my_key()}</>`)が、ブラウザの `document.cookie` の読み取りを含む独自のロケール解決を実行します。200 個の翻訳文字列があるページでは、1 回のレンダリングで 200 回ロケールが解決され、再レンダリングのたびにそれが繰り返されます。
|
|
132
|
+
|
|
133
|
+
Provider を利用するライブラリは、ロケールを **1 回だけ** 読み取り、コンテキスト(またはシグナル、ストア)に保存します。各ノードはすでにメモリ上にある値を参照するだけです。Provider のコストはわずか数百バイトです。それを省くことはレンダリングごとの CPU 負荷につながり、ベンチマークにも明確に現れています。TanStack Start において Paraglide のページ読み込み時間と言語切り替え速度は、Intlayer より一貫して劣っています(ページ読み込みで 22.1 ms vs 14.6 ms、E2E リアクティビティで 4.3 ms vs 3.2 ms)。
|
|
134
|
+
|
|
135
|
+
## 開発体験(Developer Experience)
|
|
136
|
+
|
|
137
|
+
Paraglide の信頼できる情報源(Source of Truth)は JSON ですが、JSON を直接インポートすることはありません。生成された `.js` をインポートします:
|
|
138
|
+
|
|
139
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
140
|
+
<Tab label="Paraglide" value="paraglide">
|
|
141
|
+
|
|
142
|
+
```json fileName="messages/en.json"
|
|
143
|
+
{
|
|
144
|
+
"hero_title": "Ship your app in every language"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```json fileName="messages/ja.json"
|
|
149
|
+
{
|
|
150
|
+
"hero_title": "すべての言語でアプリを公開しましょう"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx fileName="Hero.tsx"
|
|
155
|
+
// コンパイラが JSON から再生成した後にのみ存在します
|
|
156
|
+
import { m } from "../paraglide/messages.js";
|
|
157
|
+
|
|
158
|
+
export const Hero = () => <h1>{m.hero_title()}</h1>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
</Tab>
|
|
162
|
+
<Tab label="Intlayer" value="intlayer">
|
|
163
|
+
|
|
164
|
+
```ts fileName="Hero.content.ts"
|
|
165
|
+
import { t, type Dictionary } from "intlayer";
|
|
166
|
+
|
|
167
|
+
export default {
|
|
168
|
+
key: "hero",
|
|
169
|
+
content: {
|
|
170
|
+
title: t({
|
|
171
|
+
ja: "すべての言語でアプリを公開しましょう",
|
|
172
|
+
en: "Ship your app in every language",
|
|
173
|
+
}),
|
|
174
|
+
},
|
|
175
|
+
} satisfies Dictionary;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```tsx fileName="Hero.tsx"
|
|
179
|
+
import { useIntlayer } from "react-intlayer";
|
|
180
|
+
|
|
181
|
+
export const Hero = () => {
|
|
182
|
+
const { title } = useIntlayer("hero");
|
|
183
|
+
|
|
184
|
+
return <h1>{title}</h1>;
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
</Tab>
|
|
189
|
+
</Tabs>
|
|
190
|
+
|
|
191
|
+
このサイクルにはデメリットが伴います:
|
|
192
|
+
|
|
193
|
+
- JSON ファイルを変更するたびに、インポートが解決されたり型が更新されたりする前に再生成を実行する必要があります。
|
|
194
|
+
- 生成された `paraglide/` フォルダを Git にコミットするか(テキストを変更する PR ごとに生成ファイルでコンフリクトが発生)、除外するか(型チェック、テスト、CI ジョブの前に毎回生成ステップが必要になる)の二者択一になります。
|
|
195
|
+
- すべての文字列が関数呼び出しになります。単なる静的値で十分な場所を含め、至る所で定数が `m.key()` に置き換わります。
|
|
196
|
+
|
|
197
|
+
## Tree Shaking:バンドルを確認してください
|
|
198
|
+
|
|
199
|
+
Paraglide の最大のセールスポイントは、各メッセージが独立したエクスポートであるため、使用されていないメッセージが Tree Shaking によって削除されることです。Svelte + Vite のベンチマークでは、宣伝どおりに動作します。
|
|
200
|
+
|
|
201
|
+
しかし、他の環境ではそうではありませんでした。[Next.js](https://intlayer.org/ja/doc/benchmark/nextjs) の計測では、Paraglide のページはベースアプリより 14 KB 増加したのに対し、`next-intlayer` の増加は 0.3 KB にとどまりました。TanStack Start の初期計測でも、他のページのメッセージがルートバンドルに混入していることが確認されました。
|
|
202
|
+
|
|
203
|
+
Tree Shaking の成否は、バンドラー(Turbopack、Rolldown、Rollup)、メッセージのインポート方法(`import { m }` vs `import * as m`)、および副作用(Side Effects)の解析精度に左右されます。サイズを理由に Paraglide を採用する場合は、バンドルアナライザーを開いて、ご自身のアプリで正しく動作しているか確認してください。
|
|
204
|
+
|
|
205
|
+
## 動的読み込み(Dynamic Loading)の欠如
|
|
206
|
+
|
|
207
|
+
これが構造的な限界です。Paraglide には 1 言語ずつ読み込む手段がありません。各メッセージ関数が各言語の実装を静的にインポートするため、すべての言語がクライアントバンドルに含まれてしまいます。
|
|
208
|
+
|
|
209
|
+
2 言語の場合、翻訳データの半分が無駄になり、上記の測定で判明した約 50% のロケール漏洩に一致します。10 言語では 90% が無駄になり、30 言語では 97% に達します。
|
|
210
|
+
|
|
211
|
+
動的読み込みに変更しても解決にはなりません。メッセージごとに関数が分かれているため、それぞれを遅延読み込みすると数千回ものネットワークリクエストが発生してしまうからです。
|
|
212
|
+
|
|
213
|
+
Intlayer では、グローバルまたは辞書単位で柔軟に設定を選択できます:
|
|
214
|
+
|
|
215
|
+
```ts fileName="intlayer.config.ts"
|
|
216
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
217
|
+
|
|
218
|
+
const config: IntlayerConfig = {
|
|
219
|
+
internationalization: {
|
|
220
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
221
|
+
defaultLocale: Locales.ENGLISH,
|
|
222
|
+
},
|
|
223
|
+
dictionary: {
|
|
224
|
+
importMode: "dynamic", // 'static' | 'dynamic' | 'fetch'
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export default config;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
| `importMode` | クライアントに配信される内容 | vs Paraglide |
|
|
232
|
+
| ------------ | ------------------------------------------ | ----------------------------------- |
|
|
233
|
+
| `static` | ページで使用される辞書の全言語 | 理論上は同等の容量 |
|
|
234
|
+
| `dynamic` | 現在のロケールのみ、辞書ごとに遅延読み込み | N 言語の場合、**N 分の 1 に軽量化** |
|
|
235
|
+
| `fetch` | 現在のロケールのみ、Live Sync API から取得 | N 言語の場合、**N 分の 1 に軽量化** |
|
|
236
|
+
|
|
237
|
+
[ビルド変換](https://intlayer.org/ja/doc/concept/bundle-optimization) と `importMode: 'static'` を組み合わせることで、Intlayer は理論上 Paraglide とまったく同じ容量を配信します。`'dynamic'` または `'fetch'` を使用すれば、現在のロケールに必要なものだけを読み込むため、N 言語対応のアプリでは翻訳ペイロードが Paraglide と比較して N 分の 1 に削減されます。
|
|
238
|
+
|
|
239
|
+
## Paraglide が適しているユースケース
|
|
240
|
+
|
|
241
|
+
<AccordionGroup>
|
|
242
|
+
<Accordion header="言語数が少ない Svelte + Vite 環境">
|
|
243
|
+
|
|
244
|
+
スタックが Svelte + Vite であり、サポートする言語が 2〜3 言語程度であれば、Tree Shaking は仕様どおりに機能し、言語によるオーバーヘッドも小さく抑えられます。
|
|
245
|
+
|
|
246
|
+
</Accordion>
|
|
247
|
+
<Accordion header="既存の inlang ワークフロー">
|
|
248
|
+
|
|
249
|
+
チームがすでに inlang エコシステム(Fink、Sherlock、メッセージフォーマットプラグイン)を活用している場合、Paraglide はネイティブに連携できます。
|
|
250
|
+
|
|
251
|
+
</Accordion>
|
|
252
|
+
</AccordionGroup>
|
|
253
|
+
|
|
254
|
+
## ご自身のアプリで検証してみてください
|
|
255
|
+
|
|
256
|
+
無料の [i18n SEO Scanner](https://intlayer.org/i18n-seo-scanner) を使って、本番アプリケーションの転送量とロケール漏洩をチェックできます:
|
|
257
|
+
|
|
258
|
+
<ClickToOpenIframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
259
|
+
|
|
260
|
+
Intlayer の導入手順:
|
|
261
|
+
|
|
262
|
+
```bash packageManager="npm"
|
|
263
|
+
npx intlayer init --interactive
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash packageManager="pnpm"
|
|
267
|
+
pnpm dlx intlayer init --interactive
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```bash packageManager="yarn"
|
|
271
|
+
yarn dlx intlayer init --interactive
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
```bash packageManager="bun"
|
|
275
|
+
bunx intlayer init --interactive
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 関連リファレンス
|
|
279
|
+
|
|
280
|
+
- [TanStack Start i18n ベンチマーク](https://intlayer.org/ja/doc/benchmark/tanstack)
|
|
281
|
+
- [Next.js i18n ベンチマーク](https://intlayer.org/ja/doc/benchmark/nextjs)
|
|
282
|
+
- [バンドル最適化と `importMode`](https://intlayer.org/ja/doc/concept/bundle-optimization)
|
|
283
|
+
- [React 向け i18n ライブラリの選び方](https://intlayer.org/ja/blog/how-to-pick-react-i18n-library)
|
|
284
|
+
- [コンパイラ駆動型国際化のメリットとデメリット](https://intlayer.org/ja/blog/compiler-vs-declarative-i18n)
|