---
createdAt: 2026-04-20
updatedAt: 2026-05-18
title: 2026년 Vue를 위한 최고의 i18n 솔루션 - 벤치마크 리포트
description: vue-i18n, fluent-vue, Intlayer와 같은 Vue 국제화(i18n) 라이브러리를 비교합니다. 번들 크기, 누수, 반응성에 관한 상세 성능 리포트.
keywords:
  - benchmark
  - i18n
  - intl
  - vue
  - 성능
  - intlayer
slugs:
  - doc
  - benchmark
  - vue
author: Aymeric PINEAU
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-vue-template
history:
  - version: 8.9.8
    date: 2026-05-18
    changes: "GitHub 스타 비교 추가"
  - version: 8.7.12
    date: 2026-01-06
    changes: "벤치마크 초기화"
---

# Vue i18n 라이브러리 - 2026 벤치마크 리포트

이 페이지는 Vue i18n 솔루션에 대한 벤치마크 리포트입니다.

## 목차

<Toc/>

## 인터랙티브 벤치마크

<I18nBenchmark framework="vite-vue" vertical/>

## 결과 참조:

<ClickToOpenIframe
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_vue.md"
width="100%"
height="600px"
style="border:none;"
/>

> [전체 벤치마크 데이터 보기](https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_vue.md)

전체 벤치마크 저장소는 [여기](https://github.com/intlayer-org/benchmark-i18n/tree/main)에서 확인할 수 있습니다.

## 서론

국제화 솔루션은 Vue 앱에서 가장 무거운 의존성 중 하나입니다. 주요 위험은 불필요한 콘텐츠, 즉 단일 경로의 번들에 다른 페이지와 다른 로케일의 번역을 포함하는 것입니다.

앱이 성장함에 따라 이 문제는 클라이언트에 전송되는 JavaScript를 빠르게 팽창시키고 내비게이션을 느리게 만들 수 있습니다.

실제로 최적화가 가장 덜 된 구현의 경우, 국제화된 페이지가 i18n이 없는 버전보다 몇 배나 무거워질 수 있습니다.

또 다른 영향은 개발자 경험(DX)입니다: 콘텐츠 선언 방식, 타입, 네임스페이스 구성, 동적 로딩, 로케일 변경 시의 반응성 등이 포함됩니다.

## TL;DR

- **Intlayer**: 내장된 스코핑(scoping)과 동적 로딩을 제공하는 가장 가벼운 솔루션(v8.7.12).
- **vue-i18n**: 풍부한 에코시스템을 가진 업계 표준이지만, 대규모 애플리케이션에서 코드 분할 최적화가 어렵고 상당히 무거워질 수 있습니다.
- **fluent-vue**: 혁신적인 메시지 구성을 제공하지만 타입 안전성이 부족하고 극도로 무거운 솔루션입니다.

## 앱 테스트하기

i18n 누수 문제를 빠르게 파악하기 위해 [여기](https://intlayer.org/i18n-seo-scanner)에서 시도해 볼 수 있는 무료 스캐너를 구축했습니다.

<ClickToOpenIframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>

## 문제점

다국어 앱의 비용을 제한하려면 두 가지 레버가 필수적입니다:

- 페이지 / 네임스페이스별로 콘텐츠를 분리하여 필요하지 않을 때 전체 사전을 로드하지 않도록 합니다.
- 필요할 때만 올바른 로케일을 동적으로 로드합니다.

이러한 접근 방식의 기술적 한계 이해:

**동적 로딩**

동적 로딩이 없으면 대부분의 솔루션은 첫 번째 렌더링부터 메시지를 메모리에 유지하므로 경로와 로케일이 많은 앱의 경우 상당한 오버헤드가 발생합니다.

동적 로딩을 사용하면 초기 JS는 줄어들지만 언어 전환 시 추가 요청이 발생할 수 있는 장단점을 수용하게 됩니다.

**콘텐츠 분리**

`const { t } = useI18n()` + `t('a.b.c')`를 중심으로 구축된 구문은 매우 편리하지만 런타임에 큰 JSON 객체를 유지하도록 조장하는 경우가 많습니다. 이 모델은 라이브러리가 실제 페이지별 분리 전략을 제공하지 않는 한 트리 쉐이킹(tree-shaking)을 어렵게 만듭니다.

## 연구 방법론

이 벤치마크에서는 다음과 같은 라이브러리를 비교했습니다:

- `Base App` (i18n 라이브러리 없음)
- `vue-intlayer` (v8.7.12)
- `vue-i18n` (v11.4.0)
- `fluent-vue` (v3.8.2)

프레임워크는 `Vue`이며 **10개의 페이지**와 **10개의 언어**를 가진 다국어 앱을 사용했습니다.

**네 가지 로딩 전략**을 비교했습니다:

| 전략          | 네임스페이스 없음 (글로벌)                   | 네임스페이스 포함 (스코프)                                      |
| :------------ | :------------------------------------------- | :-------------------------------------------------------------- |
| **정적 로딩** | **Static**: 시작 시 모든 것을 메모리에 로드. | **Scoped static**: 네임스페이스별 분리; 시작 시 모든 것을 로드. |
| **동적 로딩** | **Dynamic**: 로케일별 온디맨드 로딩.         | **Scoped dynamic**: 네임스페이스 및 로케일별 세분화된 로딩.     |

## 전략 요약

- **Static**: 간단함. 초기 로드 후 네트워크 지연 없음. 단점: 큰 번들 크기.
- **Dynamic**: 초기 무게 감소(지연 로딩). 로케일이 많을 때 적합함.
- **Scoped static**: 복잡한 추가 네트워크 요청 없이 코드 구조를 유지(논리적 분리).
- **Scoped dynamic**: 코드 분할 및 성능을 위한 최선의 접근 방식. 현재 뷰와 활성 로케일에 필요한 것만 로드하여 메모리 사용을 최소화함.

### 측정 항목:

각 스택에 대해 실제 브라우저에서 동일한 다국어 앱을 실행한 다음, 실제로 네트워크에 전송된 데이터와 소요 시간을 기록했습니다. 크기는 **일반적인 웹 압축 후**를 기준으로 보고되는데, 이는 원시 소스 코드 크기보다 실제 다운로드 크기에 더 가깝기 때문입니다.

- **국제화 라이브러리 크기**: 번들링, 트리 쉐이킹 및 미니피케이션 후의 i18n 라이브러리 크기는 빈 컴포넌트에서의 프로바이더 + 컴포저블(composables) 코드 크기입니다. 여기에는 번역 파일 로딩은 포함되지 않습니다. 이는 콘텐츠가 들어가기 전에 라이브러리 자체가 얼마나 "무거운지"를 나타냅니다.

- **페이지당 JavaScript**: 각 벤치마크 경로에 대해 브라우저가 해당 방문을 위해 가져오는 스크립트의 양으로, 테스트 세트의 페이지 전체(및 로케일 전체)에 대한 평균입니다. 무거운 페이지는 느린 페이지입니다.

- **다른 로케일에서의 누수 (Leakage)**: 감사 대상 페이지에서 실수로 로드되는 다른 언어의 동일 페이지 콘텐츠입니다. 이 콘텐츠는 불필요하며 피해야 합니다. (예: `/en/about` 페이지 번들에 포함된 `/fr/about` 페이지 콘텐츠)

- **다른 경로에서의 누수**: 앱의 **다른 화면**에 대해서도 동일한 개념입니다. 한 페이지만 열었을 때 다른 화면의 텍스트가 함께 포함되는지 여부입니다. (예: `/en/contact` 페이지 번들에 포함된 `/en/about` 페이지 콘텐츠). 점수가 높으면 분리가 약하거나 번들이 너무 광범위함을 암시합니다.

- **평균 컴포넌트 번들 크기**: 공통 UI 요소들을 하나씩 측정하여 국제화가 일상적인 컴포넌트들을 조용히 팽창시키는지 확인합니다. 예를 들어, 컴포넌트가 재렌더링될 때 메모리에서 해당 데이터를 모두 로드하게 됩니다. 컴포넌트에 거대한 JSON을 첨부하는 것은 사용하지 않는 데이터의 거대한 저장소를 연결하는 것과 같으며, 이는 컴포넌트의 성능을 저하시킵니다.

- **언어 전환 반응성**: 앱 자체 컨트롤을 사용하여 언어를 전환하고, 방문자가 인지할 수 있을 정도로 페이지가 명확하게 전환될 때까지의 시간을 측정합니다.

- **언어 변경 후 렌더링 작업**: 전환이 진행되는 동안 인터페이스가 새로운 언어를 위해 다시 그리는 데 소요된 노력입니다. "체감" 시간과 프레임워크 비용이 다를 때 유용합니다.

- **초기 페이지 로드 시간**: 내비게이션부터 브라우저가 테스트 시나리오에 대해 페이지가 완전히 로드되었다고 판단할 때까지의 시간입니다. 콜드 스타트(cold starts)를 비교하는 데 좋습니다.

- **하이드레이션 시간 (Hydration)**: 클라이언트가 서버 HTML을 실제 클릭 가능한 상태로 변환하는 데 걸리는 시간입니다. 표의 대시(-)는 해당 구현이 이 벤치마크에서 신뢰할 수 있는 하이드레이션 수치를 제공하지 않았음을 의미합니다.

## GitHub 스타

GitHub 스타는 프로젝트의 인기, 커뮤니티 신뢰 및 장기적인 관련성을 나타내는 강력한 지표입니다. 기술적 품질을 직접적으로 측정하는 것은 아니지만, 얼마나 많은 개발자가 프로젝트가 유용하다고 생각하고 진행 상황을 팔로우하며 채택할 가능성이 있는지를 반영합니다. 프로젝트의 가치를 평가할 때 스타는 대안 간의 견인력을 비교하는 데 도움이 되며 생태계 성장에 대한 통찰력을 제공합니다.

[![Star History Chart](https://api.star-history.com/chart?repos=intlify%2Fvue-i18n%2Cfluent-vue%2Ffluent-vue%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://www.star-history.com/#intlify/vue-i18n&fluent-vue/fluent-vue&aymericzip/intlayer)

## 결과 상세

### 1 - 피해야 할 솔루션

> Vue 에코시스템에서 분명하게 피해야 할 솔루션은 없습니다.

### 2 - 수용 가능한 솔루션

**(vue-i18n)** (`vue-i18n@11.4.0`):

- **vue-i18n**은 논쟁의 여지 없이 Vue에서 가장 많이 사용되는 i18n 라이브러리이며, 많은 기능과 거대한 에코시스템을 가지고 있습니다. 하지만 내부적으로 이 솔루션은 상당히 무겁습니다. vue-i18n이 메시지 지연 로딩을 통합하더라도 스코핑(scoping) 기능이 부족합니다. 클래식 Vue SPA 앱의 경우 문제가 없으나, @nuxt/i18n을 사용하는 Nuxt 앱의 경우 모든 페이지의 메시지가 단일 페이지에 포함되는 결과를 초래합니다. 10페이지 이상의 대규모 Nuxt 앱의 경우 이는 정말 문제가 될 수 있습니다.

패키지가 매우 무겁습니다 (~24.3kb, `vue-intlayer`의 약 9배).

**(fluent-vue)** (`fluent-vue@0.5.0`):

- **fluent-vue**는 .ftl 형식을 통해 혁신을 시도합니다. 메시지 구성이 훌륭하고 시작하기 쉽습니다. 하지만 실제로는 타입 안전성의 부재로 오류 위험이 높고 디버깅에 많은 시간이 소요될 수 있습니다. 또한, 이 솔루션은 Vite 플러그인을 사용하여 메시지를 로드하는데, 이는 모든 언어의 모든 콘텐츠를 각 페이지에 강제로 로드하게 만듭니다. 게다가 이는 극도로 무거운 솔루션입니다 (~92.7kb, `vue-intlayer`의 약 34배).

### 3 - 추천 사항

**(Intlayer)** (`vue-intlayer@8.7.12`):

객관성을 위해 나의 솔루션인 `vue-intlayer`에 대해서는 직접 판단하지 않겠습니다.
