홈샌드박스쇼케이스앱문서블로그
    • English영어
      EN
    • русский러시아어
      RU
    • 日本語일본어
      JA
    • français프랑스어
      FR
    • 한국어한국어
      KO
    • 中文중국어
      ZH
    • español스페인어
      ES
    • Deutsch독일어
      DE
    • العربية아랍어
      AR
    • italiano이탈리아어
      IT
    • British English영어(영국)
      EN-GB
    • português포르투갈어
      PT
    • हिन्दी힌디어
      HI
    • Türkçe튀르키예어
      TR
    • polski폴란드어
      PL
    • Indonesia인도네시아어
      ID
    • Tiếng Việt베트남어
      VI
    • українська우크라이나어
      UK
    /
    프레임워크로 문서 필터링
    Alt+←
    Intlayer의 이점
    시작하기
    개념
    • Intlayer 작동 방식
    • 구성
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • 비주얼 편집기
    • CMS
    • CI/CD 통합
    • 번역복수형열거조건성별삽입파일중첩MarkdownHTML함수 가져오기
    • 로케일별 파일
    • 컴파일러
    • 자동 채우기
    • 테스트
    • 번들 최적화
    환경
    • Next.js 14 및 앱 라우터
      Next.js 15
      Next.js 로케일 없는 URL
      Next.js 및 페이지 라우터
      컴파일러
    • Tanstack Start Solid
    • Astro 및 React
      Astro 및 Svelte
      Astro 및 Vue
      Astro 및 Solid
      Astro 및 Preact
      Astro 및 Lit
      Astro 및 Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt 및 Vue
    • Vite 및 Solid
    • SvelteKit
    • Vite 및 Preact
    • Vite 및 Vanilla JS
    • Vite 및 Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native 및 Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx 및 React
    Plugins
    • JSON
    • gettext (.po)
    VS Code 확장 기능
    에이전트
    • MCP 서버
    • 에이전트 기술
    릴리스
    • v8
    • v7
    • v6
    벤치마크
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    블로그
    질문 발표
    1. Documentation
    2. 벤치마크
    3. Next.js
    작가: Aymeric PINEAU
    생성:2026-04-20마지막 업데이트:2026-05-18
    GitHub에서 애플리케이션 템플릿 보기

    이 페이지에는 애플리케이션 템플릿이 제공됩니다.

    이 문서를 원하는 AI 어시스턴트에 참조하세요
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    이 페이지와 원하는 AI 어시스턴트를 사용하여 문서를 요약합니다

    버전 기록

    1. "GitHub 스타 비교 추가"
      v8.9.82026. 5. 18.
    2. "벤치마크 초기화"
      v8.7.52026. 1. 6.

    이 페이지의 콘텐츠는 AI를 사용하여 번역되었습니다.

    영어 원본 내용의 최신 버전을 보기
    문서 수정

    이 문서를 개선할 아이디어가 있으시면 GitHub에 풀 리퀘스트를 제출하여 자유롭게 기여해 주세요.

    문서에 대한 GitHub 링크
    복사

    문서의 Markdown을 클립보드에 복사

    Next.js i18n 라이브러리 - 2026 벤치마크 리포트

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

    목차

    인터랙티브 벤치마크

    결과 참조:

    intlayer.org
    전체 벤치마크 데이터 보기

    전체 벤치마크 저장소는 여기에서 확인할 수 있습니다.

    서론

    국제화 라이브러리는 애플리케이션에 큰 영향을 미칩니다. 주요 위험은 사용자가 한 페이지만 방문할 때 모든 페이지와 모든 언어의 콘텐츠를 로드하는 것입니다.

    앱이 성장함에 따라 번들 크기가 기하급수적으로 커질 수 있으며, 이는 성능 저하를 눈에 띄게 유발할 수 있습니다.

    예를 들어, 가장 좋지 않은 사례의 경우 국제화 후 페이지 크기가 거의 4배까지 커질 수 있습니다.

    i18n 라이브러리의 또 다른 영향은 개발 속도 저하입니다. 컴포넌트를 여러 언어를 지원하는 다국어 콘텐츠로 변환하는 작업은 시간이 많이 걸립니다.

    이 문제는 해결하기 어렵기 때문에 DX에 초점을 맞춘 솔루션부터 성능이나 확장성에 초점을 맞춘 솔루션 등 다양한 대안이 존재합니다.

    Intlayer는 이러한 모든 차원에서 최적화를 시도합니다.

    TL;DR

    • Intlayer & next-translate: Next.js 성능을 위한 최선의 선택으로, 가장 작은 풋프린트와 최고의 정적 렌더링 지원을 제공합니다.
    • next-intl: 가장 트렌디한 옵션이지만 대규모 애플리케이션을 위해 최적화하기에는 무겁고 복잡합니다.
    • next-i18next: 인기가 많고 플러그인이 풍부하지만 상당한 번들 무게를 가집니다(Intlayer의 약 3배).
    • 피해야 할 솔루션: gt-next 및 lingo.dev는 심각한 성능 문제, 벤더 종속성 및 빌드를 중단시키는 버그로 인해 권장하지 않습니다.

    앱 테스트하기

    이러한 문제들을 파악하기 위해 여기에서 시도해 볼 수 있는 무료 스캐너를 구축했습니다.

    intlayer.org

    문제점

    다국어 앱이 번들에 미치는 영향을 제한하는 두 가지 주요 방법이 있습니다:

    • 번들러가 특정 페이지에서 사용되지 않는 콘텐츠를 트리 쉐이킹(tree-shake)할 수 있도록 JSON(또는 콘텐츠)을 파일 / 변수 / 네임스페이스별로 분리합니다.
    • 사용자의 언어로만 페이지 콘텐츠를 동적으로 로드합니다.

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

    동적 로딩

    Webpack이나 Turbopack을 사용하고 generateStaticParams가 정의되어 있더라도 [locale]/page.tsx와 같은 경로를 선언할 때 번들러는 locale을 정적 상수로 취급하지 않습니다. 즉, 모든 언어의 콘텐츠를 각 페이지로 끌어올 수 있음을 의미합니다. 이를 제한하는 주요 방법은 동적 임포트(예: import('./locales/${locale}.json'))를 통해 콘텐츠를 로드하는 것입니다.

    빌드 시점에 발생하는 일은 Next.js가 로케일당 하나의 JS 번들(예: ./locales_fr_12345.js)을 배출하는 것입니다. 사이트가 클라이언트에 전송된 후 페이지가 실행되면 브라우저는 필요한 JS 파일(예: ./locales_fr_12345.js)에 대해 추가 HTTP 요청을 수행합니다.

    같은 문제를 해결하는 또 다른 방법은 fetch()를 사용하여 JSON을 동적으로 로드하는 것입니다. 이는 JSON이 /public에 있는 경우 Tolgee가 작동하는 방식이거나, 콘텐츠 로딩을 위해 getStaticProps에 의존하는 next-translate가 작동하는 방식입니다. 흐름은 동일합니다: 브라우저는 애셋을 로드하기 위해 추가 HTTP 요청을 합니다.

    콘텐츠 분리

    const t = useTranslation() + t('my-object.my-sub-object.my-key')와 같은 구문을 사용하는 경우, 라이브러리가 키를 분석하고 해결할 수 있도록 일반적으로 전체 JSON이 번들에 포함되어야 합니다. 이로 인해 페이지에서 사용되지 않더라도 많은 콘텐츠가 함께 전송됩니다.

    이를 완화하기 위해 일부 라이브러리는 페이지별로 로드할 네임스페이스를 선언하도록 요구합니다(예: next-i18next, next-intl, lingui, next-translate, next-international).

    반면, Paraglide는 빌드 전에 JSON을 const en_my_var = () => 'my value'와 같은 평면적인 심볼로 변환하는 추가 단계를 추가합니다. 이론적으로 이는 페이지에서 사용되지 않는 콘텐츠의 트리 쉐이킹을 가능하게 합니다. 나중에 살펴보겠지만, 이 방법에도 장단점이 있습니다.

    마지막으로, Intlayer는 빌드 시 최적화를 적용하여 useIntlayer('my-key')가 해당 콘텐츠로 직접 대체되도록 합니다.

    연구 방법론

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

    • Base App (i18n 라이브러리 없음)
    • next-intlayer (v8.7.12)
    • next-i18next (v16.0.5)
    • next-intl (v4.9.1)
    • @lingui/core (v5.3.0)
    • next-translate (v3.1.2)
    • next-international (v1.3.1)
    • @inlang/paraglide-js (v2.15.1)
    • @tolgee/react (v7.0.0)
    • @lingo.dev/compiler (v0.4.0)
    • wuchale (v0.22.11)
    • gt-next (v6.16.5)

    Next.js 버전 16.2.4와 App Router를 사용했습니다.

    10개의 페이지와 10개의 언어를 가진 다국어 앱을 구축했습니다.

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

    테이블의 모든 내용 표시

    테이블을 모달로 열어 모든 데이터를 명확하게 확인

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

    전략 요약

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

    측정 항목:

    각 스택에 대해 실제 브라우저에서 동일한 다국어 앱을 실행한 다음, 실제로 네트워크를 통해 전송된 데이터와 소요된 시간을 기록했습니다. 크기는 원본 소스 코드 수보다 사람들이 실제로 다운로드하는 것에 더 가까운 일반적인 웹 압축 후 크기로 보고됩니다.

    • 국제화 라이브러리 크기: 번들링, 트리 쉐이킹 및 미니피케이션 후의 i18n 라이브러리 크기입니다. 빈 컴포넌트 내의 프로바이더(예: NextIntlClientProvider) + 훅(예: useTranslations) 코드의 크기를 의미합니다. 여기에는 번역 파일의 로딩은 포함되지 않습니다. 콘텐츠가 들어가기 전 라이브러리 자체가 얼마나 무거운지에 대한 답을 줍니다.

    • 페이지당 JavaScript: 각 벤치마크 경로에 대해 브라우저가 해당 방문을 위해 가져오는 스크립트의 양으로, 스위트 내 페이지 전체(및 보고서에서 합산하는 경우 로케일 전체)의 평균값입니다. 무거운 페이지는 느린 페이지입니다.

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

    • 다른 경로에서의 누수: 앱의 다른 화면에 대해서도 동일한 개념입니다. 한 페이지만 열었는데 다른 페이지의 텍스트가 함께 따라오는지 여부입니다(예: /en/contact 페이지 번들에 포함된 /en/about 페이지 콘텐츠). 높은 점수는 빈약한 분리 또는 지나치게 넓은 번들을 나타냅니다.

    • 평균 컴포넌트 번들 크기: 공통 UI 조각들을 하나의 거대한 앱 수치 안에 숨기는 대신 하나씩 측정합니다. 이는 국제화가 일상의 컴포넌트를 조용히 부풀리는지 여부를 보여줍니다. 예를 들어, 컴포넌트가 재렌더링되면 메모리에서 그 모든 데이터를 로드하게 됩니다. 거대한 JSON을 컴포넌트에 연결하는 것은 컴포넌트 성능을 저하시키는 사용되지 않는 데이터의 큰 저장소를 연결하는 것과 같습니다.

    • 언어 전환 반응성: 앱 자체 컨트롤을 사용하여 언어를 전환하고 페이지가 명확하게 전환될 때까지 걸리는 시간을 측정합니다. 실험실의 미세한 단계가 아닌 방문자가 체감하는 시간입니다.

    • 언어 전환 후 렌더링 작업: 좁은 범위의 후속 조치로, 전환이 진행된 후 인터페이스가 새 언어로 다시 그려지는 데 소요된 노력을 측정합니다. "체감" 시간과 프레임워크 비용이 다를 때 유용합니다.

    • 초기 페이지 로드 시간: 탐색부터 테스트한 시나리오에 대해 브라우저가 페이지를 완전히 로드한 것으로 간주할 때까지의 시간입니다. 콜드 스타트(cold starts)를 비교하는 데 좋습니다.

    • 하이드레이션 시간: 앱이 이를 노출할 때, 클라이언트가 서버 HTML을 실제로 클릭할 수 있는 것으로 전환하는 데 걸리는 시간입니다. 표의 대시(-)는 해당 구현이 이 벤치마크에서 신뢰할 수 있는 하이드레이션 수치를 제공하지 않았음을 의미합니다.

    GitHub 스타

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

    Star History Chart

    결과 상세

    1 - 피해야 할 솔루션

    gt-next나 lingo.dev와 같은 일부 솔루션은 분명히 피하는 것이 좋습니다. 이들은 벤더 종속성(vendor lock-in)과 코드베이스 오염을 결합합니다. 이를 구현하기 위해 많은 시간을 투자했음에도 불구하고, TanStack Start나 Next.js에서 제대로 작동하지 않았습니다.

    발생한 문제점들:

    (General Translation) ([email protected]):

    • 110kb 앱의 경우 gt-next는 440kb 이상의 추가 데이터를 추가합니다.
    • General Translation을 사용한 가장 첫 번째 빌드에서 Quota Exceeded, please upgrade your plan 메시지가 표시되었습니다.
    • 번역이 렌더링되지 않습니다. Error: <T> used on the client-side outside of <GTProvider> 오류가 발생하며, 이는 라이브러리의 버그로 보입니다.
    • gt-next를 구현하는 동안 라이브러리의 이슈도 발견했습니다: does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser 오류로 애플리케이션이 중단되었습니다. 이 문제를 보고한 후 관리자는 24시간 이내에 수정했습니다.
    • 이 라이브러리는 Next.js 페이지의 정적 렌더링을 차단합니다.

    (Lingo.dev) (@lingo.dev/[email protected]):

    • AI 쿼터 초과로 빌드가 완전히 차단되었습니다. 즉, 비용을 지불하지 않으면 프로덕션에 출시할 수 없습니다.
    • 컴파일러가 번역된 콘텐츠의 거의 40%를 놓치고 있었습니다. 작동시키기 위해 모든 .map을 평면적인 컴포넌트 블록으로 다시 작성해야 했습니다.
    • CLI에 버그가 있어 아무 이유 없이 설정 파일을 초기화하곤 했습니다.
    • 빌드 시 새 콘텐츠가 추가되면 생성된 JSON을 완전히 삭제했습니다. 결과적으로 소수의 키가 300개 이상의 기존 키를 지워버릴 수 있었습니다.

    2 - 실험적인 솔루션

    (Wuchale) ([email protected]):

    Wuchale의 아이디어는 흥미롭지만 아직 실행 가능하지 않습니다. 반응성 문제에 부딪혔고 앱을 작동시키기 위해 프로바이더의 강제 재렌더링이 필요했습니다. 문서 또한 상당히 불명확하여 온보딩이 어렵습니다.

    (Paraglide) (@inlang/[email protected]):

    Paraglide는 혁신적이고 잘 설계된 접근 방식을 제공합니다. 그럼에도 불구하고 이 벤치마크에서는 광고된 트리 쉐이킹이 나의 Next.js 또는 TanStack Start 설정에서 작동하지 않았습니다. 워크플로우와 DX는 다른 옵션보다 복잡합니다. 개인적으로 푸시할 때마다 JS 파일을 다시 생성해야 하는 것이 싫습니다. 이는 PR을 통한 지속적인 머지 충돌 위험을 만듭니다. 또한 이 도구는 Next.js보다 Vite에 더 집중하는 것으로 보입니다. 마지막으로, 다른 솔루션과 비교할 때 Paraglide는 콘텐츠를 렌더링하기 위해 현재 로케일을 조회하는 스토어(예: React context)를 사용하지 않습니다. 파싱되는 각 노드에 대해 localStorage / 쿠키 등에서 로케일을 요청합니다. 이는 컴포넌트 반응성에 영향을 주는 불필요한 로직 실행으로 이어집니다.

    paraglide에 관한 참고 사항: 이 솔루션은 임포트를 위해 코드베이스에 코드를 주입하므로 벤치마크 리포트의 '라이브러리 크기' 지표는 거의 0에 가깝습니다. 코드 생성은 좋은 기능입니다. 사용되는 함수가 필요한 로직(모든 접두사 vs 접두사 없음, 쿠키 vs 스토리지 등)만 포함하기 때문입니다. 이에 비해 Intlayer는 빌드 시 환경 변수 주입을 통해 로직에 따라 번들러가 콘텐츠를 트리 쉐이킹하도록 강제합니다. 이 덕분에 paraglide와 intlayer는 i18next나 next-intl보다 6~10배 가벼운 솔루션이 됩니다.

    3 - 수용 가능한 솔루션

    (Tolgee) (@tolgee/[email protected]):

    Tolgee는 앞에서 언급한 많은 문제들을 해결합니다. 비슷한 도구들보다 채택하기 더 어렵다고 느꼈습니다. 타입 안전성을 제공하지 않아 컴파일 시점에 누락된 키를 찾는 것도 어렵습니다. 누락된 키 감지 기능을 추가하기 위해 Tolgee의 함수를 나의 함수로 래핑해야 했습니다.

    (Next Intl) ([email protected]):

    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과 같은 네임스페이스로 분리된 경우 정적 렌더링이 여전히 깨집니다.

    (Next I18next) ([email protected]):

    next-i18next는 JavaScript 앱 i18n 솔루션 중 초기에 등장했기 때문에 가장 인기 있는 옵션일 것입니다. 많은 커뮤니티 플러그인을 보유하고 있습니다. next-intl과 같은 주요 단점을 공유합니다. 패키지가 특히 무겁습니다(I18nProvider + useTranslation의 경우 약 18kb로, next-intlayer의 약 3배입니다).

    메시지 형식도 다릅니다: next-intl은 ICU MessageFormat을 사용하는 반면, i18next는 자체 형식을 사용합니다.

    (Next International) ([email protected]):

    next-international 또한 위의 문제들을 다루지만 next-intl이나 next-i18next와 크게 다르지 않습니다. 네임스페이스별 번역을 위한 scopedT()를 포함하지만, 이를 사용해도 번들 크기에는 거의 영향이 없습니다.

    (Lingui) (@lingui/[email protected]):

    Lingui는 종종 찬사를 받습니다. 개인적으로 lingui extract / lingui compile 워크플로우가 대안들보다 복잡하다고 느꼈으며 명확한 장점이 없었습니다. 또한 AI를 혼란스럽게 하는 일관성 없는 구문(예: t(), t'', i18n.t(), <Trans>)을 발견했습니다.

    4 - 추천 사항

    (Next Translate) ([email protected]):

    t() 스타일의 API를 선호한다면 next-translate가 주요 추천 사항입니다. Webpack / Turbopack 로더를 통해 getStaticProps에서 네임스페이스를 로드하는 next-translate-plugin을 통해 우아하게 작동합니다. 또한 여기에서 가장 가벼운 옵션입니다(약 2.5kb). 네임스페이싱의 경우 설정 파일에서 페이지 또는 경로별 네임스페이스를 정의하는 방식이 잘 생각되어 있으며 next-intl이나 next-i18next와 같은 주요 대안보다 유지 관리가 쉽습니다. 버전 3.1.2에서 정적 렌더링이 작동하지 않았고 Next.js가 동적 렌더링으로 폴백(fallback)되는 것을 확인했습니다.

    (Intlayer) ([email protected]):

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

    개인적인 의견

    이 의견은 개인적인 것이며 벤치마크 결과에는 영향을 미치지 않습니다. i18n 세계에서는 번역된 콘텐츠를 위해 const t = useTranslation('xx') + <>{t('xx.xx')}</>와 같은 패턴에 대한 합의가 자주 보입니다.

    React 앱에서 함수를 ReactNode로 주입하는 것은 내 견해로는 안티 패턴입니다. 또한 피할 수 있는 복잡성과 JavaScript 실행 오버헤드(거의 눈에 띄지 않더라도)를 추가합니다.

    벤치마크
    TanStack
    Alt+→

    이 페이지에서

      토론은 익명이며 일반적인 문제를 해결하기 위해 정기적으로 검토됩니다. 기능 아이디어, 문서에 대한 피드백 또는 Intlayer와 관련된 모든 것을 자유롭게 공유하세요, 이 의견을 로드맵 구성과 제품 개선에 활용합니다.

      동적 JSON 로드

      런타임에 번역을 지연 로드합니다

      범위가 지정된 JSON (네임스페이싱)

      페이지별 번역 네임스페이스

      I18n 성능 벤치마크

      데이터 없음

      이 측정항목은 무엇인가요?

      국제화 라이브러리 번들의 총 gzip 압축 크기입니다. 여기에는 트리 쉐이킹 및 미니피케이션 후의 프로바이더 및 콘텐츠 검색 로직만 포함됩니다.

      왜 중요한가요?

      라이브러리 크기가 작으면 초기 JavaScript 페이로드가 줄어들어 클라이언트에서 다운로드 및 실행 시간이 빨라집니다.

      보기 형식