@intlayer/docs 8.7.4 → 8.7.5
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/de/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/id/list_i18n_technologies/frameworks/svelte.md +0 -2
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/pl/list_i18n_technologies/frameworks/svelte.md +0 -2
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/blog/vi/list_i18n_technologies/frameworks/svelte.md +0 -2
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +0 -2
- package/dist/cjs/generated/docs.entry.cjs +60 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +60 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +3 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/index.md +29 -0
- package/docs/ar/benchmark/nextjs.md +227 -0
- package/docs/ar/benchmark/tanstack.md +193 -0
- package/docs/ar/intlayer_with_tanstack.md +0 -2
- package/docs/de/benchmark/index.md +29 -0
- package/docs/de/benchmark/nextjs.md +227 -0
- package/docs/de/benchmark/tanstack.md +193 -0
- package/docs/en/benchmark/___NOTE.md +82 -0
- package/docs/en/benchmark/___nextjs.md +195 -0
- package/docs/en/benchmark/___tanstack.md +187 -0
- package/docs/en/benchmark/index.md +29 -0
- package/docs/en/benchmark/nextjs.md +228 -0
- package/docs/en/benchmark/tanstack.md +217 -0
- package/docs/en-GB/benchmark/index.md +29 -0
- package/docs/en-GB/benchmark/nextjs.md +228 -0
- package/docs/en-GB/benchmark/tanstack.md +193 -0
- package/docs/es/benchmark/index.md +29 -0
- package/docs/es/benchmark/nextjs.md +226 -0
- package/docs/es/benchmark/tanstack.md +193 -0
- package/docs/fr/benchmark/index.md +29 -0
- package/docs/fr/benchmark/nextjs.md +227 -0
- package/docs/fr/benchmark/tanstack.md +193 -0
- package/docs/hi/benchmark/index.md +29 -0
- package/docs/hi/benchmark/nextjs.md +227 -0
- package/docs/hi/benchmark/tanstack.md +193 -0
- package/docs/id/benchmark/index.md +29 -0
- package/docs/id/benchmark/nextjs.md +227 -0
- package/docs/id/benchmark/tanstack.md +193 -0
- package/docs/id/intlayer_with_react_native+expo.md +0 -2
- package/docs/it/benchmark/index.md +29 -0
- package/docs/it/benchmark/nextjs.md +227 -0
- package/docs/it/benchmark/tanstack.md +193 -0
- package/docs/ja/benchmark/index.md +29 -0
- package/docs/ja/benchmark/nextjs.md +227 -0
- package/docs/ja/benchmark/tanstack.md +193 -0
- package/docs/ko/benchmark/index.md +29 -0
- package/docs/ko/benchmark/nextjs.md +227 -0
- package/docs/ko/benchmark/tanstack.md +193 -0
- package/docs/ko/intlayer_with_tanstack.md +0 -2
- package/docs/pl/benchmark/index.md +29 -0
- package/docs/pl/benchmark/nextjs.md +227 -0
- package/docs/pl/benchmark/tanstack.md +193 -0
- package/docs/pt/benchmark/index.md +29 -0
- package/docs/pt/benchmark/nextjs.md +227 -0
- package/docs/pt/benchmark/tanstack.md +193 -0
- package/docs/ru/benchmark/index.md +29 -0
- package/docs/ru/benchmark/nextjs.md +227 -0
- package/docs/ru/benchmark/tanstack.md +193 -0
- package/docs/tr/benchmark/index.md +29 -0
- package/docs/tr/benchmark/nextjs.md +227 -0
- package/docs/tr/benchmark/tanstack.md +193 -0
- package/docs/uk/benchmark/index.md +29 -0
- package/docs/uk/benchmark/nextjs.md +227 -0
- package/docs/uk/benchmark/tanstack.md +193 -0
- package/docs/vi/benchmark/index.md +29 -0
- package/docs/vi/benchmark/nextjs.md +227 -0
- package/docs/vi/benchmark/tanstack.md +193 -0
- package/docs/zh/benchmark/index.md +29 -0
- package/docs/zh/benchmark/nextjs.md +227 -0
- package/docs/zh/benchmark/tanstack.md +193 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +60 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: 2026년 Next.js를 위한 최고의 i18n 솔루션 - 벤치마크 리포트
|
|
5
|
+
description: next-intl, next-i18next, Intlayer와 같은 Next.js 국제화(i18n) 라이브러리를 비교합니다. 번들 크기, 누수, 반응성에 관한 상세 성능 리포트.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- nextjs
|
|
11
|
+
- 성능
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- nextjs
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.5
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "벤치마크 초기화"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Next.js i18n 라이브러리 — 2026 벤치마크 리포트
|
|
26
|
+
|
|
27
|
+
이 페이지는 Next.js i18n 솔루션에 대한 벤치마크 리포트입니다.
|
|
28
|
+
|
|
29
|
+
## 목차
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## 인터랙티브 벤치마크
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
36
|
+
|
|
37
|
+
## 결과 참조:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-nextjs.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-nextjs.md
|
|
47
|
+
|
|
48
|
+
전체 벤치마크 저장소는 [여기](https://github.com/intlayer-org/benchmark-i18n)에서 확인할 수 있습니다.
|
|
49
|
+
|
|
50
|
+
## 서론
|
|
51
|
+
|
|
52
|
+
국제화 라이브러리는 애플리케이션에 큰 영향을 미칩니다. 주요 위험은 사용자가 한 페이지만 방문할 때 모든 페이지와 모든 언어의 콘텐츠를 로드하는 것입니다.
|
|
53
|
+
|
|
54
|
+
앱이 성장함에 따라 번들 크기가 기하급수적으로 커질 수 있으며, 이는 성능 저하를 눈에 띄게 유발할 수 있습니다.
|
|
55
|
+
|
|
56
|
+
예를 들어, 가장 좋지 않은 사례의 경우 국제화 후 페이지 크기가 거의 4배까지 커질 수 있습니다.
|
|
57
|
+
|
|
58
|
+
i18n 라이브러리의 또 다른 영향은 개발 속도 저하입니다. 컴포넌트를 여러 언어를 지원하는 다국어 콘텐츠로 변환하는 작업은 시간이 많이 걸립니다.
|
|
59
|
+
|
|
60
|
+
이 문제는 해결하기 어렵기 때문에 DX에 초점을 맞춘 솔루션부터 성능이나 확장성에 초점을 맞춘 솔루션 등 다양한 대안이 존재합니다.
|
|
61
|
+
|
|
62
|
+
Intlayer는 이러한 모든 차원에서 최적화를 시도합니다.
|
|
63
|
+
|
|
64
|
+
## 앱 테스트하기
|
|
65
|
+
|
|
66
|
+
이러한 문제들을 파악하기 위해 [여기](https://intlayer.org/i18n-seo-scanner)에서 시도해 볼 수 있는 무료 스캐너를 구축했습니다.
|
|
67
|
+
|
|
68
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
69
|
+
|
|
70
|
+
## 문제점
|
|
71
|
+
|
|
72
|
+
다국어 앱이 번들에 미치는 영향을 제한하는 두 가지 주요 방법이 있습니다:
|
|
73
|
+
|
|
74
|
+
- 번들러가 특정 페이지에서 사용되지 않는 콘텐츠를 트리 쉐이킹(tree-shake)할 수 있도록 JSON(또는 콘텐츠)을 파일 / 변수 / 네임스페이스별로 분리합니다.
|
|
75
|
+
- 사용자의 언어로만 페이지 콘텐츠를 동적으로 로드합니다.
|
|
76
|
+
|
|
77
|
+
이러한 접근 방식의 기술적 한계:
|
|
78
|
+
|
|
79
|
+
**동적 로딩**
|
|
80
|
+
|
|
81
|
+
Webpack이나 Turbopack을 사용하고 `generateStaticParams`가 정의되어 있더라도 `[locale]/page.tsx`와 같은 경로를 선언할 때 번들러는 `locale`을 정적 상수로 취급하지 않습니다. 즉, 모든 언어의 콘텐츠를 각 페이지로 끌어올 수 있음을 의미합니다. 이를 제한하는 주요 방법은 동적 임포트(예: `import('./locales/${locale}.json')`)를 통해 콘텐츠를 로드하는 것입니다.
|
|
82
|
+
|
|
83
|
+
빌드 시점에 발생하는 일은 Next.js가 로케일당 하나의 JS 번들(예: `./locales_fr_12345.js`)을 배출하는 것입니다. 사이트가 클라이언트에 전송된 후 페이지가 실행되면 브라우저는 필요한 JS 파일(예: `./locales_fr_12345.js`)에 대해 추가 HTTP 요청을 수행합니다.
|
|
84
|
+
|
|
85
|
+
> 같은 문제를 해결하는 또 다른 방법은 `fetch()`를 사용하여 JSON을 동적으로 로드하는 것입니다. 이는 JSON이 `/public`에 있는 경우 `Tolgee`가 작동하는 방식이거나, 콘텐츠 로딩을 위해 `getStaticProps`에 의존하는 `next-translate`가 작동하는 방식입니다. 흐름은 동일합니다: 브라우저는 애셋을 로드하기 위해 추가 HTTP 요청을 합니다.
|
|
86
|
+
|
|
87
|
+
**콘텐츠 분리**
|
|
88
|
+
|
|
89
|
+
`const t = useTranslation()` + `t('my-object.my-sub-object.my-key')`와 같은 구문을 사용하는 경우, 라이브러리가 키를 분석하고 해결할 수 있도록 일반적으로 전체 JSON이 번들에 포함되어야 합니다. 이로 인해 페이지에서 사용되지 않더라도 많은 콘텐츠가 함께 전송됩니다.
|
|
90
|
+
|
|
91
|
+
이를 완화하기 위해 일부 라이브러리는 페이지별로 로드할 네임스페이스를 선언하도록 요구합니다(예: `next-i18next`, `next-intl`, `lingui`, `next-translate`, `next-international`).
|
|
92
|
+
|
|
93
|
+
반면, `Paraglide`는 빌드 전에 JSON을 `const en_my_var = () => 'my value'`와 같은 평면적인 심볼로 변환하는 추가 단계를 추가합니다. 이론적으로 이는 페이지에서 사용되지 않는 콘텐츠의 트리 쉐이킹을 가능하게 합니다. 나중에 살펴보겠지만, 이 방법에도 장단점이 있습니다.
|
|
94
|
+
|
|
95
|
+
마지막으로, `Intlayer`는 빌드 시 최적화를 적용하여 `useIntlayer('my-key')`가 해당 콘텐츠로 직접 대체되도록 합니다.
|
|
96
|
+
|
|
97
|
+
## 연구 방법론
|
|
98
|
+
|
|
99
|
+
이 벤치마크에서는 다음과 같은 라이브러리를 비교했습니다:
|
|
100
|
+
|
|
101
|
+
- `Base App` (i18n 라이브러리 없음)
|
|
102
|
+
- `next-intlayer` (v8.7.5)
|
|
103
|
+
- `next-i18next` (v16.0.5)
|
|
104
|
+
- `next-intl` (v4.9.1)
|
|
105
|
+
- `@lingui/core` (v5.3.0)
|
|
106
|
+
- `next-translate` (v3.1.2)
|
|
107
|
+
- `next-international` (v1.3.1)
|
|
108
|
+
- `@inlang/paraglide-js` (v2.15.1)
|
|
109
|
+
- `tolgee` (v7.0.0)
|
|
110
|
+
- `@lingo.dev/compiler` (v0.4.0)
|
|
111
|
+
- `wuchale` (v0.22.11)
|
|
112
|
+
- `gt-next` (v6.16.5)
|
|
113
|
+
|
|
114
|
+
Next.js 버전 `16.2.4`와 App Router를 사용했습니다.
|
|
115
|
+
|
|
116
|
+
**10개의 페이지**와 **10개의 언어**를 가진 다국어 앱을 구축했습니다.
|
|
117
|
+
|
|
118
|
+
**네 가지 로딩 전략**을 비교했습니다:
|
|
119
|
+
|
|
120
|
+
| 전략 | 네임스페이스 없음 (글로벌) | 네임스페이스 포함 (스코프) |
|
|
121
|
+
| :------------ | :------------------------------------------- | :-------------------------------------------------------------- |
|
|
122
|
+
| **정적 로딩** | **Static**: 시작 시 모든 것을 메모리에 로드. | **Scoped static**: 네임스페이스별 분리; 시작 시 모든 것을 로드. |
|
|
123
|
+
| **동적 로딩** | **Dynamic**: 로케일별 온디맨드 로딩. | **Scoped dynamic**: 네임스페이스 및 로케일별 세분화된 로딩. |
|
|
124
|
+
|
|
125
|
+
## 전략 요약
|
|
126
|
+
|
|
127
|
+
- **Static**: 간단함. 초기 로드 후 네트워크 지연 없음. 단점: 큰 번들 크기.
|
|
128
|
+
- **Dynamic**: 초기 무게 감소(지연 로딩). 로케일이 많을 때 적합함.
|
|
129
|
+
- **Scoped static**: 복잡한 추가 네트워크 요청 없이 코드 구조를 유지(논리적 분리).
|
|
130
|
+
- **Scoped dynamic**: 코드 분할 및 성능을 위한 최선의 접근 방식. 현재 뷰와 활성 로케일에 필요한 것만 로드하여 메모리 사용을 최소화함.
|
|
131
|
+
|
|
132
|
+
### 측정 항목:
|
|
133
|
+
|
|
134
|
+
각 스택에 대해 실제 브라우저에서 동일한 다국어 앱을 실행한 다음, 실제로 네트워크를 통해 전송된 데이터와 소요된 시간을 기록했습니다. 크기는 원본 소스 코드 수보다 사람들이 실제로 다운로드하는 것에 더 가까운 **일반적인 웹 압축 후** 크기로 보고됩니다.
|
|
135
|
+
|
|
136
|
+
- **국제화 라이브러리 크기**: 번들링, 트리 쉐이킹 및 미니피케이션 후의 i18n 라이브러리 크기입니다. 빈 컴포넌트 내의 프로바이더(예: `NextIntlClientProvider`) + 훅(예: `useTranslations`) 코드의 크기를 의미합니다. 여기에는 번역 파일의 로딩은 포함되지 않습니다. 콘텐츠가 들어가기 전 라이브러리 자체가 얼마나 무거운지에 대한 답을 줍니다.
|
|
137
|
+
|
|
138
|
+
- **페이지당 JavaScript**: 각 벤치마크 경로에 대해 브라우저가 해당 방문을 위해 가져오는 스크립트의 양으로, 스위트 내 페이지 전체(및 보고서에서 합산하는 경우 로케일 전체)의 평균값입니다. 무거운 페이지는 느린 페이지입니다.
|
|
139
|
+
|
|
140
|
+
- **다른 로케일에서의 누수**: 감시 대상 페이지에서 실수로 로드되는 동일한 페이지의 다른 언어 콘텐츠입니다. 이 콘텐츠는 불필요하며 피해야 합니다(예: `/en/about` 페이지 번들에 포함된 `/fr/about` 페이지 콘텐츠).
|
|
141
|
+
|
|
142
|
+
- **다른 경로에서의 누수**: 앱의 **다른 화면**에 대해서도 동일한 개념입니다. 한 페이지만 열었는데 다른 페이지의 텍스트가 함께 따라오는지 여부입니다(예: `/en/contact` 페이지 번들에 포함된 `/en/about` 페이지 콘텐츠). 높은 점수는 빈약한 분리 또는 지나치게 넓은 번들을 나타냅니다.
|
|
143
|
+
|
|
144
|
+
- **평균 컴포넌트 번들 크기**: 공통 UI 조각들을 하나의 거대한 앱 수치 안에 숨기는 대신 **하나씩** 측정합니다. 이는 국제화가 일상의 컴포넌트를 조용히 부풀리는지 여부를 보여줍니다. 예를 들어, 컴포넌트가 재렌더링되면 메모리에서 그 모든 데이터를 로드하게 됩니다. 거대한 JSON을 컴포넌트에 연결하는 것은 컴포넌트 성능을 저하시키는 사용되지 않는 데이터의 큰 저장소를 연결하는 것과 같습니다.
|
|
145
|
+
|
|
146
|
+
- **언어 전환 반응성**: 앱 자체 컨트롤을 사용하여 언어를 전환하고 페이지가 명확하게 전환될 때까지 걸리는 시간을 측정합니다. 실험실의 미세한 단계가 아닌 방문자가 체감하는 시간입니다.
|
|
147
|
+
|
|
148
|
+
- **언어 전환 후 렌더링 작업**: 좁은 범위의 후속 조치로, 전환이 진행된 후 인터페이스가 새 언어로 다시 그려지는 데 소요된 노력을 측정합니다. "체감" 시간과 프레임워크 비용이 다를 때 유용합니다.
|
|
149
|
+
|
|
150
|
+
- **초기 페이지 로드 시간**: 탐색부터 테스트한 시나리오에 대해 브라우저가 페이지를 완전히 로드한 것으로 간주할 때까지의 시간입니다. 콜드 스타트(cold starts)를 비교하는 데 좋습니다.
|
|
151
|
+
|
|
152
|
+
- **하이드레이션 시간**: 앱이 이를 노출할 때, 클라이언트가 서버 HTML을 실제로 클릭할 수 있는 것으로 전환하는 데 걸리는 시간입니다. 표의 대시(-)는 해당 구현이 이 벤치마크에서 신뢰할 수 있는 하이드레이션 수치를 제공하지 않았음을 의미합니다.
|
|
153
|
+
|
|
154
|
+
## 결과 상세
|
|
155
|
+
|
|
156
|
+
### 1 — 피해야 할 솔루션
|
|
157
|
+
|
|
158
|
+
`gt-next`나 `lingo.dev`와 같은 일부 솔루션은 분명히 피하는 것이 좋습니다. 이들은 벤더 종속성(vendor lock-in)과 코드베이스 오염을 결합합니다. 이를 구현하기 위해 많은 시간을 투자했음에도 불구하고, TanStack Start나 Next.js에서 제대로 작동하지 않았습니다.
|
|
159
|
+
|
|
160
|
+
발생한 문제점들:
|
|
161
|
+
|
|
162
|
+
**(General Translation)** (`gt-next@6.16.5`):
|
|
163
|
+
|
|
164
|
+
- 110kb 앱의 경우 `gt-react`는 440kb 이상의 추가 데이터를 추가합니다.
|
|
165
|
+
- General Translation을 사용한 가장 첫 번째 빌드에서 `Quota Exceeded, please upgrade your plan` 메시지가 표시되었습니다.
|
|
166
|
+
- 번역이 렌더링되지 않습니다. `Error: <T> used on the client-side outside of <GTProvider>` 오류가 발생하며, 이는 라이브러리의 버그로 보입니다.
|
|
167
|
+
- **gt-tanstack-start-react**를 구현하는 동안 라이브러리의 [이슈](https://github.com/generaltranslation/gt/issues/1210#event-24510646961)도 발견했습니다: `does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser` 오류로 애플리케이션이 중단되었습니다. 이 문제를 보고한 후 관리자는 24시간 이내에 수정했습니다.
|
|
168
|
+
- 이 라이브러리는 Next.js 페이지의 정적 렌더링을 차단합니다.
|
|
169
|
+
|
|
170
|
+
**(Lingo.dev)** (`@lingo.dev/compiler@0.4.0`):
|
|
171
|
+
|
|
172
|
+
- AI 쿼터 초과로 빌드가 완전히 차단되었습니다. 즉, 비용을 지불하지 않으면 프로덕션에 출시할 수 없습니다.
|
|
173
|
+
- 컴파일러가 번역된 콘텐츠의 거의 40%를 놓치고 있었습니다. 작동시키기 위해 모든 `.map`을 평면적인 컴포넌트 블록으로 다시 작성해야 했습니다.
|
|
174
|
+
- CLI에 버그가 있어 아무 이유 없이 설정 파일을 초기화하곤 했습니다.
|
|
175
|
+
- 빌드 시 새 콘텐츠가 추가되면 생성된 JSON을 완전히 삭제했습니다. 결과적으로 소수의 키가 300개 이상의 기존 키를 지워버릴 수 있었습니다.
|
|
176
|
+
|
|
177
|
+
### 2 — 실험적인 솔루션
|
|
178
|
+
|
|
179
|
+
**(Wuchale)** (`wuchale@0.22.11`):
|
|
180
|
+
|
|
181
|
+
`Wuchale`의 아이디어는 흥미롭지만 아직 실행 가능하지 않습니다. 반응성 문제에 부딪혔고 앱을 작동시키기 위해 프로바이더의 강제 재렌더링이 필요했습니다. 문서 또한 상당히 불명확하여 온보딩이 어렵습니다.
|
|
182
|
+
|
|
183
|
+
**(Paraglide)** (`@inlang/paraglide-js@2.15.1`):
|
|
184
|
+
|
|
185
|
+
`Paraglide`는 혁신적이고 잘 설계된 접근 방식을 제공합니다. 그럼에도 불구하고 이 벤치마크에서는 광고된 트리 쉐이킹이 나의 Next.js 또는 TanStack Start 설정에서 작동하지 않았습니다. 워크플로우와 DX는 다른 옵션보다 복잡합니다.
|
|
186
|
+
개인적으로 푸시할 때마다 JS 파일을 다시 생성해야 하는 것이 싫습니다. 이는 PR을 통한 지속적인 머지 충돌 위험을 만듭니다. 또한 이 도구는 Next.js보다 Vite에 더 집중하는 것으로 보입니다.
|
|
187
|
+
마지막으로, 다른 솔루션과 비교할 때 Paraglide는 콘텐츠를 렌더링하기 위해 현재 로케일을 조회하는 스토어(예: React context)를 사용하지 않습니다. 파싱되는 각 노드에 대해 localStorage / 쿠키 등에서 로케일을 요청합니다. 이는 컴포넌트 반응성에 영향을 주는 불필요한 로직 실행으로 이어집니다.
|
|
188
|
+
|
|
189
|
+
### 3 — 수용 가능한 솔루션
|
|
190
|
+
|
|
191
|
+
**(Tolgee)** (`tolgee@7.0.0`):
|
|
192
|
+
|
|
193
|
+
`Tolgee`는 앞에서 언급한 많은 문제들을 해결합니다. 비슷한 도구들보다 채택하기 더 어렵다고 느꼈습니다. 타입 안전성을 제공하지 않아 컴파일 시점에 누락된 키를 찾는 것도 어렵습니다. 누락된 키 감지 기능을 추가하기 위해 Tolgee의 함수를 나의 함수로 래핑해야 했습니다.
|
|
194
|
+
|
|
195
|
+
**(Next Intl)** (`next-intl@4.9.1`):
|
|
196
|
+
|
|
197
|
+
`next-intl`은 가장 유행하는 옵션이며 AI 에이전트들이 가장 많이 추천하는 옵션이지만, 내 견해로는 성능 면에서 잘못된 추천입니다. 시작하기는 쉽습니다. 실제로는 누수를 제한하기 위한 최적화가 복잡합니다. 동적 로딩 + 네임스페이싱 + TypeScript 타입을 결합하면 개발 속도가 크게 느려집니다. 패키지 또한 상당히 무겁습니다(`NextIntlClientProvider` + `useTranslations`의 경우 약 13kb로, `next-intlayer`의 2배 이상입니다). **next-intl**은 Next.js 페이지의 정적 렌더링을 차단하곤 했습니다. `setRequestLocale()`이라는 헬퍼를 제공합니다. `en.json` / `fr.json`과 같은 중앙 집중식 파일의 경우 일부 해결된 것으로 보이지만, 콘텐츠가 `en/shared.json` / `fr/shared.json` / `es/shared.json`과 같은 네임스페이스로 분리된 경우 정적 렌더링이 여전히 깨집니다.
|
|
198
|
+
|
|
199
|
+
**(Next I18next)** (`next-i18next@16.0.5`):
|
|
200
|
+
|
|
201
|
+
`next-i18next`는 JavaScript 앱 i18n 솔루션 중 초기에 등장했기 때문에 가장 인기 있는 옵션일 것입니다. 많은 커뮤니티 플러그인을 보유하고 있습니다. `next-intl`과 같은 주요 단점을 공유합니다. 패키지가 특히 무겁습니다(`I18nProvider` + `useTranslation`의 경우 약 18kb로, `next-intlayer`의 약 3배입니다).
|
|
202
|
+
|
|
203
|
+
메시지 형식도 다릅니다: `next-intl`은 ICU MessageFormat을 사용하는 반면, `i18next`는 자체 형식을 사용합니다.
|
|
204
|
+
|
|
205
|
+
**(Next International)** (`next-international@1.3.1`):
|
|
206
|
+
|
|
207
|
+
`next-international` 또한 위의 문제들을 다루지만 `next-intl`이나 `next-i18next`와 크게 다르지 않습니다. 네임스페이스별 번역을 위한 `scopedT()`를 포함하지만, 이를 사용해도 번들 크기에는 거의 영향이 없습니다.
|
|
208
|
+
|
|
209
|
+
**(Lingui)** (`@lingui/core@5.3.0`):
|
|
210
|
+
|
|
211
|
+
`Lingui`는 종종 찬사를 받습니다. 개인적으로 `lingui extract` / `lingui compile` 워크플로우가 대안들보다 복잡하다고 느꼈으며 명확한 장점이 없었습니다. 또한 AI를 혼란스럽게 하는 일관성 없는 구문(예: `t()`, `t''`, `i18n.t()`, `<Trans>`)을 발견했습니다.
|
|
212
|
+
|
|
213
|
+
### 4 — 추천 사항
|
|
214
|
+
|
|
215
|
+
**(Next Translate)** (`next-translate@3.1.2`):
|
|
216
|
+
|
|
217
|
+
`t()` 스타일의 API를 선호한다면 `next-translate`가 주요 추천 사항입니다. Webpack / Turbopack 로더를 통해 `getStaticProps`에서 네임스페이스를 로드하는 `next-translate-plugin`을 통해 우아하게 작동합니다. 또한 여기에서 가장 가벼운 옵션입니다(약 2.5kb). 네임스페이싱의 경우 설정 파일에서 페이지 또는 경로별 네임스페이스를 정의하는 방식이 잘 생각되어 있으며 **next-intl**이나 **next-i18next**와 같은 주요 대안보다 유지 관리가 쉽습니다. 버전 `3.1.2`에서 정적 렌더링이 작동하지 않았고 Next.js가 동적 렌더링으로 폴백(fallback)되는 것을 확인했습니다.
|
|
218
|
+
|
|
219
|
+
**(Intlayer)** (`next-intlayer@8.7.5`):
|
|
220
|
+
|
|
221
|
+
객관성을 위해 나의 솔루션인 `next-intlayer`에 대해서는 직접 판단하지 않겠습니다.
|
|
222
|
+
|
|
223
|
+
### 개인적인 의견
|
|
224
|
+
|
|
225
|
+
이 의견은 개인적인 것이며 벤치마크 결과에는 영향을 미치지 않습니다. i18n 세계에서는 번역된 콘텐츠를 위해 `const t = useTranslation('xx')` + `<>{t('xx.xx')}</>`와 같은 패턴에 대한 합의가 자주 보입니다.
|
|
226
|
+
|
|
227
|
+
React 앱에서 함수를 `ReactNode`로 주입하는 것은 내 견해로는 안티 패턴입니다. 또한 피할 수 있는 복잡성과 JavaScript 실행 오버헤드(거의 눈에 띄지 않더라도)를 추가합니다.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: 2026년 TanStack Start를 위한 최고의 i18n 솔루션 - 벤치마크 리포트
|
|
5
|
+
description: react-i18next, use-intl, Intlayer와 같은 TanStack Start 국제화 라이브러리를 비교합니다. 번들 크기, 누수, 반응성에 관한 상세 성능 리포트.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- tanstack
|
|
11
|
+
- 성능
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- tanstack
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-tanstack-start-template
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.5
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "벤치마크 초기화"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# TanStack Start i18n 라이브러리 — 2026 벤치마크 리포트
|
|
26
|
+
|
|
27
|
+
이 페이지는 TanStack Start i18n 솔루션에 대한 벤치마크 리포트입니다.
|
|
28
|
+
|
|
29
|
+
## 목차
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## 인터랙티브 벤치마크
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="tanstack" vertical/>
|
|
36
|
+
|
|
37
|
+
## 결과 참조:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-tanstack.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-tanstack.md
|
|
47
|
+
|
|
48
|
+
전체 벤치마크 저장소는 [여기](https://github.com/intlayer-org/benchmark-i18n/tree/main)에서 확인할 수 있습니다.
|
|
49
|
+
|
|
50
|
+
## 서론
|
|
51
|
+
|
|
52
|
+
국제화 솔루션은 React 앱에서 가장 무거운 의존성 중 하나입니다. TanStack Start에서 주요 위험은 불필요한 콘텐츠, 즉 단일 경로의 번들에 다른 페이지와 다른 로케일의 번역을 포함하는 것입니다.
|
|
53
|
+
|
|
54
|
+
앱이 성장함에 따라 이 문제는 클라이언트에 전송되는 JavaScript를 빠르게 팽창시키고 내비게이션을 느리게 만들 수 있습니다.
|
|
55
|
+
|
|
56
|
+
실제로 최적화가 가장 덜 된 구현의 경우, 국제화된 페이지가 i18n이 없는 버전보다 몇 배나 무거워질 수 있습니다.
|
|
57
|
+
|
|
58
|
+
또 다른 영향은 개발자 경험(DX)입니다: 콘텐츠 선언 방식, 타입, 네임스페이스 구성, 동적 로딩, 로케일 변경 시의 반응성 등이 포함됩니다.
|
|
59
|
+
|
|
60
|
+
## 앱 테스트하기
|
|
61
|
+
|
|
62
|
+
i18n 누수 문제를 빠르게 파악하기 위해 [여기](https://intlayer.org/i18n-seo-scanner)에서 시도해 볼 수 있는 무료 스캐너를 구축했습니다.
|
|
63
|
+
|
|
64
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
65
|
+
|
|
66
|
+
## 문제점
|
|
67
|
+
|
|
68
|
+
다국어 앱의 비용을 제한하려면 두 가지 레버가 필수적입니다:
|
|
69
|
+
|
|
70
|
+
- 페이지 / 네임스페이스별로 콘텐츠를 분리하여 필요하지 않을 때 전체 사전을 로드하지 않도록 합니다.
|
|
71
|
+
- 필요할 때만 올바른 로케일을 동적으로 로드합니다.
|
|
72
|
+
|
|
73
|
+
이러한 접근 방식의 기술적 한계 이해:
|
|
74
|
+
|
|
75
|
+
**동적 로딩**
|
|
76
|
+
|
|
77
|
+
동적 로딩이 없으면 대부분의 솔루션은 첫 번째 렌더링부터 메시지를 메모리에 유지하므로 경로와 로케일이 많은 앱의 경우 상당한 오버헤드가 발생합니다.
|
|
78
|
+
|
|
79
|
+
동적 로딩을 사용하면 초기 JS는 줄어들지만 언어 전환 시 추가 요청이 발생할 수 있는 장단점을 수용하게 됩니다.
|
|
80
|
+
|
|
81
|
+
**콘텐츠 분리**
|
|
82
|
+
|
|
83
|
+
`const t = useTranslation()` + `t('a.b.c')`를 중심으로 구축된 구문은 매우 편리하지만 런타임에 큰 JSON 객체를 유지하도록 조장하는 경우가 많습니다. 이 모델은 라이브러리가 실제 페이지별 분리 전략을 제공하지 않는 한 트리 쉐이킹을 어렵게 만듭니다.
|
|
84
|
+
|
|
85
|
+
## 연구 방법론
|
|
86
|
+
|
|
87
|
+
이 벤치마크에서는 다음과 같은 라이브러리를 비교했습니다:
|
|
88
|
+
|
|
89
|
+
- `Base App` (i18n 라이브러리 없음)
|
|
90
|
+
- `react-intlayer` (v8.7.5-canary.0)
|
|
91
|
+
- `react-i18next` (v17.0.2)
|
|
92
|
+
- `use-intl` (v4.9.1)
|
|
93
|
+
- `@lingui/core` (v5.3.0)
|
|
94
|
+
- `@inlang/paraglide-js` (v2.15.1)
|
|
95
|
+
- `tolgee` (v7.0.0)
|
|
96
|
+
- `react-intl` (v10.1.1)
|
|
97
|
+
- `wuchale` (v0.22.11)
|
|
98
|
+
- `gt-react` (vlatest)
|
|
99
|
+
- `lingo.dev` (v0.133.9)
|
|
100
|
+
|
|
101
|
+
프레임워크는 `TanStack Start`이며 **10개의 페이지**와 **10개의 언어**를 가진 다국어 앱을 사용했습니다.
|
|
102
|
+
|
|
103
|
+
**네 가지 로딩 전략**을 비교했습니다:
|
|
104
|
+
|
|
105
|
+
| 전략 | 네임스페이스 없음 (글로벌) | 네임스페이스 포함 (스코프) |
|
|
106
|
+
| :------------ | :------------------------------------------- | :-------------------------------------------------------------- |
|
|
107
|
+
| **정적 로딩** | **Static**: 시작 시 모든 것을 메모리에 로드. | **Scoped static**: 네임스페이스별 분리; 시작 시 모든 것을 로드. |
|
|
108
|
+
| **동적 로딩** | **Dynamic**: 로케일별 온디맨드 로딩. | **Scoped dynamic**: 네임스페이스 및 로케일별 세분화된 로딩. |
|
|
109
|
+
|
|
110
|
+
## 전략 요약
|
|
111
|
+
|
|
112
|
+
- **Static**: 간단함. 초기 로드 후 네트워크 지연 없음. 단점: 큰 번들 크기.
|
|
113
|
+
- **Dynamic**: 초기 무게 감소(지연 로딩). 로케일이 많을 때 적합함.
|
|
114
|
+
- **Scoped static**: 복잡한 추가 네트워크 요청 없이 코드 구조를 유지(논리적 분리).
|
|
115
|
+
- **Scoped dynamic**: 코드 분할 및 성능을 위한 최선의 접근 방식. 현재 뷰와 활성 로케일에 필요한 것만 로드하여 메모리 사용을 최소화함.
|
|
116
|
+
|
|
117
|
+
## 결과 상세
|
|
118
|
+
|
|
119
|
+
### 1 — 피해야 할 솔루션
|
|
120
|
+
|
|
121
|
+
`gt-react`나 `lingo.dev`와 같은 일부 솔루션은 분명히 피해야 합니다. 이들은 벤더 종속성과 코드베이스 오염을 결합합니다. 설상가상으로 이를 구현하기 위해 많은 시간을 투자했음에도 불구하고 TanStack Start에서 제대로 작동하지 않았습니다(Next.js의 `gt-next`와 유사).
|
|
122
|
+
|
|
123
|
+
발생한 문제점들:
|
|
124
|
+
|
|
125
|
+
**(General Translation)** (`gt-react@latest`):
|
|
126
|
+
|
|
127
|
+
- 약 110kb 앱의 경우 `gt-react`는 440kb 이상의 추가 데이터를 추가할 수 있습니다(동일 벤치마크의 Next.js 구현에서 확인된 규모).
|
|
128
|
+
- General Translation을 사용한 가장 첫 번째 빌드에서 `Quota Exceeded, please upgrade your plan` 메시지가 표시되었습니다.
|
|
129
|
+
- 번역이 렌더링되지 않습니다. `Error: <T> used on the client-side outside of <GTProvider>` 오류가 발생하며, 이는 라이브러리의 버그로 보입니다.
|
|
130
|
+
- **gt-tanstack-start-react**를 구현하는 동안 라이브러리의 [이슈](https://github.com/generaltranslation/gt/issues/1210#event-24510646961)도 발견했습니다: `does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser` 오류로 애플리케이션이 중단되었습니다. 이 문제를 보고한 후 관리자는 24시간 이내에 수정했습니다.
|
|
131
|
+
- 이 라이브러리들은 `initializeGT()` 함수를 통해 안티 패턴을 사용하여 번들이 깨끗하게 트리 쉐이킹되는 것을 방해합니다.
|
|
132
|
+
|
|
133
|
+
**(Lingo.dev)** (`lingo.dev@0.133.9`):
|
|
134
|
+
|
|
135
|
+
- AI 쿼터 초과(또는 차단 중인 서버 의존성)로 인해 비용을 지불하지 않으면 빌드 / 프로덕션 출시가 위험해집니다.
|
|
136
|
+
- 컴파일러가 번역된 콘텐츠의 거의 40%를 놓치고 있었습니다. 작동시키기 위해 모든 `.map`을 평면적인 컴포넌트 블록으로 다시 작성해야 했습니다.
|
|
137
|
+
- CLI에 버그가 있어 아무 이유 없이 설정 파일을 초기화하곤 했습니다.
|
|
138
|
+
- 빌드 시 새 콘텐츠가 추가되면 생성된 JSON을 완전히 삭제했습니다. 결과적으로 소수의 키가 수백 개의 기존 키를 지워버릴 수 있었습니다.
|
|
139
|
+
- TanStack Start에서 라이브러리의 반응성 문제를 겪었습니다: 로케일 변경 시 작동시키기 위해 프로바이더의 강제 재렌더링이 필요했습니다.
|
|
140
|
+
|
|
141
|
+
### 2 — 실험적인 솔루션
|
|
142
|
+
|
|
143
|
+
**(Wuchale)** (`wuchale@0.22.11`):
|
|
144
|
+
|
|
145
|
+
`Wuchale`의 아이디어는 흥미롭지만 아직 실행 가능한 솔루션은 아닙니다. 이 라이브러리에서 반응성 문제를 겪었으며 TanStack Start에서 앱을 작동시키기 위해 프로바이더의 강제 재렌더링이 필요했습니다. 문서 또한 상당히 불명확하여 온보딩이 어렵습니다.
|
|
146
|
+
|
|
147
|
+
### 3 — 수용 가능한 솔루션
|
|
148
|
+
|
|
149
|
+
**(Paraglide)** (`@inlang/paraglide-js@2.15.1`):
|
|
150
|
+
|
|
151
|
+
`Paraglide`는 혁신적이고 잘 설계된 접근 방식을 제공합니다. 그럼에도 불구하고 이 벤치마크에서는 광고된 트리 쉐이킹이 나의 Next.js 구현이나 TanStack Start에서 작동하지 않았습니다. 워크플로우와 DX 또한 다른 옵션보다 복잡합니다. 개인적으로 푸시할 때마다 JS 파일을 다시 생성해야 하는 것을 선호하지 않으며, 이는 PR을 통한 개발자들 간의 지속적인 머지 충돌 위험을 만듭니다.
|
|
152
|
+
|
|
153
|
+
**(Tolgee)** (`tolgee@7.0.0`):
|
|
154
|
+
|
|
155
|
+
`Tolgee`는 앞에서 언급한 많은 문제들을 해결합니다. 비슷한 접근 방식을 가진 다른 도구들보다 시작하기 더 어렵다고 느꼈습니다. 타입 안전성을 제공하지 않아 컴파일 시점에 누락된 키를 찾는 것도 매우 어렵습니다. 누락된 키 감지 기능을 추가하기 위해 Tolgee의 API를 나의 API로 래핑해야 했습니다.
|
|
156
|
+
|
|
157
|
+
TanStack Start에서도 반응성 문제가 있었습니다: 로케일 변경 시 프로바이더를 강제 재렌더링하고 로케일 변경 이벤트를 구독하여 다른 언어로의 로딩이 올바르게 작동하도록 해야 했습니다.
|
|
158
|
+
|
|
159
|
+
**(use-intl)** (`use-intl@4.9.1`):
|
|
160
|
+
|
|
161
|
+
`use-intl`은 React 에코시스템에서 가장 유행하는 "intl" 조각 중 하나이며(`next-intl`과 같은 계열) AI 에이전트들에 의해 자주 추천되지만, 내 견해로는 성능 우선 환경에서 잘못된 선택입니다. 시작하기는 꽤 간단합니다. 실제로는 누수를 최적화하고 제한하는 프로세스가 상당히 복잡합니다. 마찬가지로 동적 로딩 + 네임스페이싱 + TypeScript 타입을 결합하면 개발 속도가 크게 느려집니다.
|
|
162
|
+
|
|
163
|
+
TanStack Start에서는 Next.js 전용 함정(`setRequestLocale`, 정적 렌더링)을 피할 수 있지만 핵심 문제는 동일합니다: 엄격한 규율이 없으면 번들은 금세 너무 많은 메시지를 포함하게 되고 경로별 네임스페이스 유지는 고통스러워집니다.
|
|
164
|
+
|
|
165
|
+
**(react-i18next)** (`react-i18next@17.0.2`):
|
|
166
|
+
|
|
167
|
+
`react-i18next`는 JavaScript 앱 i18n 요구 사항을 충족시킨 초창기 솔루션 중 하나였기 때문에 가장 인기 있는 옵션일 것입니다. 또한 특정 문제를 해결하기 위한 광범위한 커뮤니티 플러그인 세트를 보유하고 있습니다.
|
|
168
|
+
|
|
169
|
+
여전히 `t('a.b.c')` 위에 구축된 스택과 동일한 주요 단점을 공유합니다: 최적화는 가능하지만 시간이 매우 많이 소요되며, 대규모 프로젝트는 나쁜 관행(네임스페이스 + 동적 로딩 + 타입)에 빠질 위험이 있습니다.
|
|
170
|
+
|
|
171
|
+
메시지 형식도 다릅니다: `use-intl`은 ICU MessageFormat을 사용하는 반면, `i18next`는 자체 형식을 사용하므로 이들을 섞어서 사용하면 도구 기술이나 마이그레이션이 복잡해집니다.
|
|
172
|
+
|
|
173
|
+
**(Lingui)** (`@lingui/core@5.3.0`):
|
|
174
|
+
|
|
175
|
+
`Lingui`는 종종 찬사를 받습니다. 개인적으로 `lingui extract` / `lingui compile` 워크플로우가 다른 접근 방식보다 복잡하다고 느꼈으며 이 TanStack Start 벤치마크에서 명확한 장점이 없었습니다. 또한 AI를 혼란스럽게 하는 일관성 없는 구문(예: `t()`, `t''`, `i18n.t()`, `<Trans>`)을 발견했습니다.
|
|
176
|
+
|
|
177
|
+
**(react-intl)** (`react-intl@10.1.1`):
|
|
178
|
+
|
|
179
|
+
`react-intl`은 Format.js 팀의 성능 중심 구현입니다. DX는 여전히 장황합니다: `const intl = useIntl()` + `intl.formatMessage({ id: "xx.xx" })`는 복잡성과 추가 JavaScript 작업을 가중시키고 글로벌 i18n 인스턴스를 React 트리의 많은 노드에 묶어둡니다.
|
|
180
|
+
|
|
181
|
+
### 4 — 추천 사항
|
|
182
|
+
|
|
183
|
+
이 TanStack Start 벤치마크에는 `next-translate`(Next.js 플러그인 + `getStaticProps`)에 상응하는 직접적인 대안이 없습니다. 성숙한 에코시스템과 `t()` API를 진정으로 원하는 팀에게는 `react-i18next`와 `use-intl`이 "합리적인" 선택으로 남겠지만, 누수를 피하기 위해 최적화하는 데 많은 시간을 투자할 것을 각오해야 합니다.
|
|
184
|
+
|
|
185
|
+
**(Intlayer)** (`react-intlayer@8.7.5-canary.0`):
|
|
186
|
+
|
|
187
|
+
객관성을 위해 나의 솔루션인 `react-intlayer`에 대해서는 직접 판단하지 않겠습니다.
|
|
188
|
+
|
|
189
|
+
### 개인적인 의견
|
|
190
|
+
|
|
191
|
+
이 의견은 개인적인 것이며 벤치마크 결과에는 영향을 미치지 않습니다. 그럼에도 불구하고 i18n 세계에서는 번역된 콘텐츠를 위해 `const t = useTranslation('xx')` + `<>{t('xx.xx')}</>`와 같은 패턴에 대한 합의가 자주 보입니다.
|
|
192
|
+
|
|
193
|
+
React 앱에서 함수를 `ReactNode`로 주입하는 것은 내 견해로는 안티 패턴입니다. 또한 피할 수 있는 복잡성과 JavaScript 실행 오버헤드(거의 눈에 띄지 않더라도)를 추가합니다.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-20
|
|
4
|
+
title: Benchmark bibliotek i18n
|
|
5
|
+
description: Dowiedz się, jak Intlayer wypada na tle innych bibliotek i18n pod względem wydajności i rozmiaru pakietu.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- nextjs
|
|
11
|
+
- tanstack
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
history:
|
|
17
|
+
- version: 8.7.5
|
|
18
|
+
date: 2026-01-06
|
|
19
|
+
changes: "Inicjalizacja benchmarka"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Benchmark - Raport
|
|
23
|
+
|
|
24
|
+
Benchmark Bloom to pakiet testów wydajnościowych, który mierzy rzeczywisty wpływ bibliotek i18n (internacjonalizacji) w wielu frameworkach React i przy różnych strategiach ładowania.
|
|
25
|
+
|
|
26
|
+
Poniżej znajdziesz szczegółowe raporty i dokumentację techniczną dla każdego frameworka:
|
|
27
|
+
|
|
28
|
+
- [**Raport benchmarku Next.js**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/benchmark/nextjs.md)
|
|
29
|
+
- [**Raport benchmarku TanStack Start**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/benchmark/tanstack.md)
|