Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту
Вміст цієї сторінки перекладено за допомогою штучного інтелекту.
Переглянути останню версію оригінального вмісту англійськоюЯкщо у вас є ідея щодо покращення цієї документації, будь ласка, долучіться, надіславши pull request на GitHub.
Посилання на документацію на GitHubСкопіювати документацію у форматі Markdown в буфер обміну
next-intl проти Intlayer: Бенчмарк інтернаціоналізації (i18n) у React та Next.js

next-intl є найпопулярнішою бібліотекою i18n для Next.js. Intlayer, це альтернатива на основі компілятора з областю видимості на рівні компонентів. Обидва рішення локалізують застосунок App Router. Питання полягає в тому, скільки коштує кожне з них після збирання проєкту.
Ця стаття не є посібником. Це порівняння, підтверджене даними з Benchmark Bloom, відкритого набору бенчмарків, який створює однаковий застосунок із кожною бібліотекою та вимірює те, що браузер фактично завантажує та виконує.
Коротко (tl;dr):next-intlдодає щонайменше +12.6 КБ gzip на кожній сторінці лише через свій runtime і призводить до витоку ~90% рядків з інших сторінок у стандартних конфігураціях (staticтаdynamic). Щоб усунути цей витік, потрібно вручну розбивати каталоги на простори імен та підключати їх окремо для кожної сторінки. Натомість компіляторIntlayerгарантує 0% витоку, втричі менші компоненти та лише +0.3 КБ понад базовий додаток без будь-яких ручних налаштувань.
Короткий огляд
- next-intl - Стандарт спільноти Next.js. Централізовані словники JSON для кожної мови, повна підтримка ICU MessageFormat і глибока інтеграція з обробкою запитів та маршрутизацією Next.js.
- Intlayer - Модель контенту, орієнтована на компоненти. Файли
.content.tsрозташовані поруч із компонентами, компілятор часу збирання автоматично виконує tree-shaking та ліниве завантаження для кожного компонента і локалі, а також генерує суворі типи TypeScript.
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
Значки оновлюються автоматично.
Порівняння функціональності
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Функція | Intlayer (react-intlayer / next-intlayer) | next-intl (next-intl / use-intl) |
|---|---|---|
| Переклади поруч із компонентами | ✅ Так, .content.ts поруч із кожним компонентом | ❌ Централізовані словники JSON у папці messages/ |
| Інтеграція з TypeScript | ✅ Суворі типи генеруються автоматично з контенту | ⚠️ Підтримується через ручне налаштування global.d.ts |
| Виявлення відсутніх перекладів | ✅ Помилка TypeScript + помилка/попередження під час збирання | ⚠️ У runtime повертає ключ або генерує помилку залежно від налаштувань |
| Багатий контент (JSX / Markdown / компоненти) | ✅ Пряма підтримка | ⚠️ Через t.rich() з передачею компонентів зіставлення |
| Підтримка ICU MessageFormat | ⚠️ У розробці | ✅ Так, повна підтримка ICU |
| Синхронні серверні компоненти | ✅ useIntlayer з next-intlayer/server працює у будь-якому дочірньому компоненті | ❌ Вимагає передачі перекладів через props від асинхронного предка |
| Tree-shaking | ✅ Автоматично для кожного компонента і локалі | ⚠️ Вимагає ручного поділу на простори імен та використання pick() |
| Ліниве завантаження (Lazy loading) | ✅ Один рядок конфігурації (importMode: 'dynamic') | ⚠️ Вимагає ручного динамічного імпорту в getRequestConfig |
| Візуальний редактор / CMS | ✅ Безкоштовний Візуальний редактор + додаткова CMS | ❌ Немає |
| Переклад за допомогою ШІ | ✅ Вбудовано, використовує ваші власні API-ключі | ❌ Немає |
| Сервер MCP та навички агентів | ✅ Так | ❌ Немає |
Бенчмарк
Що вимірювалося
Набір тестів Benchmark Bloom збирає однаковий додаток з кожною бібліотекою: 10 сторінок (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 локалей (en, fr, es, de, it, pt, zh, ja, ko, ru), однакові компоненти та ідентичний вміст. Сторінки вимірюються мовами en та fr. Кожна бібліотека протестована в чотирьох стратегіях завантаження:
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Стратегія | Опис | Хто це використовує |
|---|---|---|
| static | Усі локалі та всі сторінки запаковані разом на старті | Швидкі прототипи, код, згенерований ШІ |
| dynamic | Завантажується лише активна локаль, але відразу для всіх сторінок | Більшість проєктів |
| scoped-static | Простори імен на кожен маршрут, без лінивого завантаження | Рідко |
| scoped-dynamic | Простори імен на кожен маршрут + ліниве завантаження. Лише поточна сторінка поточної мови | Додатки з суворим бюджетом продуктивності |
Intlayer не має варіанта "scoped": компілятор автоматично обмежує контекст контенту для кожного компонента, тому рядки static і dynamic уже оптимізовані за маршрутами.
Для кожного збирання фіксувалося:
- Розмір бібліотеки (Lib size): розмір gzip порожнього компонента, який імпортує лише бібліотеку i18n.
- JS сторінки (Page JS): кількість стиснутого gzip JavaScript на сторінку.
- % витоку локалі (Locale leak %): частка рядків мови, яку користувач не переглядає.
- % витоку сторінки (Page leak %): частка рядків сторінки, на якій користувач не перебуває.
- Середній розмір компонента (Component avg): середній розмір gzip кожного компонента, скомпільованого окремо.
- Реактивність E2E: час між перемиканням мови та оновленням
html[lang]у DOM. - Гідратація: тривалість фази гідратації React.
Наведені дані отримані під час тестування від 2026-09-12 зnext-intl4.14.2 таintlayer9.5.1.
Результати на Next.js (App Router)
Виберіть метрики та бібліотеки, які вас цікавлять:
Метрика
Динамічне завантаження JSON
Ледаче завантаження перекладів під час виконання
Обмежений JSON (простори імен)
Простори імен перекладу для кожної сторінки
Що це за метрика?
Загальний стиснений у gzip розмір пакета бібліотеки інтернаціоналізації. Він включає лише провайдер та логіку отримання контенту після tree-shaking та мініфікації.
Чому це важливо?
Менший розмір бібліотеки зменшує початкове завантаження JavaScript, що призводить до швидшого завантаження та виконання на клієнті.
Перегляд як
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Бібліотека | Стратегія | Розмір Lib (gz) | Сер. JS сторінки (gz) | Витік локалі | Витік сторінки | Сер. компонента (gz) | Реактивність E2E | Гідратація |
|---|---|---|---|---|---|---|---|---|
| Базовий додаток (без i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-intl | static | 14.7 KB | 153.6 KB | 4.2% | 89.8% | 21.8 KB | 16.0 ms | 14.7 ms |
next-intl | dynamic | 14.7 KB | 153.6 KB | 9.7% | 89.9% | 21.8 KB | 15.6 ms | 14.8 ms |
next-intl | scoped-static | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 80.1 KB | 17.9 ms | 17.4 ms |
next-intl | scoped-dynamic | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 22.9 KB | 17.8 ms | 16.8 ms |
next-intlayer | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
@intlayer/next-intl (сумісн.) | static | 8.0 KB | 147.5 KB | 0.0% | 0.0% | 8.1 KB | 14.5 ms | 12.8 ms |
@intlayer/next-intl (сумісн.) | dynamic | 8.0 KB | 148.7 KB | 0.0% | 0.0% | 8.1 KB | 11.7 ms | 12.8 ms |
Як інтерпретувати результати
- Витрати runtime. Базовий додаток важить 141.0 КБ на сторінку.
next-intlзбільшує це значення до 153.6 КБ (+12.6 КБ gzip на кожній сторінці), тоді як Intlayer додає лише 141.3 КБ (+0.3 КБ). - Витік контенту. У найпоширеніших конфігураціях (
staticтаdynamic)next-intlвідправляє на кожну сторінку ~90% рядків з інших сторінок, оскільки весь файлen.jsonпотрапляє до клієнтського провайдера. Щоб зменшити цей показник до 0%, потрібен складний ручний поділ на простори імен, тоді як в Intlayer це працює за замовчуванням. - Розмір компонента. Компонент із
useTranslations()важить у середньому 21.8 КБ; той самий компонент зuseIntlayer()важить лише 6.9 КБ.
Повна таблиця, кожна бібліотека та кожна стратегія, у звіті бенчмарку Next.js.
Результати на TanStack Start (use-intl)
use-intl, це незалежне від фреймворку ядро next-intl. Той самий API, той самий формат повідомлень. Порівняння його з intlayer на TanStack Start усуває особливості Next.js із рівняння.
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Бібліотека | Стратегія | Розмір Lib (gz) | Сер. JS сторінки (gz) | Витік локалі | Витік сторінки | Сер. компонента (gz) | Реактивність E2E |
|---|---|---|---|---|---|---|---|
| Базовий додаток (без i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms |
use-intl | static | 14.1 KB | 179.8 KB | 50.0% | 89.8% | 76.0 KB | 6.7 ms |
use-intl | dynamic | 14.1 KB | 119.4 KB | 0.0% | 89.8% | 75.9 KB | 7.0 ms |
use-intl | scoped-static | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 20.9 ms |
use-intl | scoped-dynamic | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 13.3 ms |
intlayer | static | 5.0 KB | 125.8 KB | 50.0% | 0.0% | 8.1 KB | 3.2 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms |
@intlayer/use-intl (сумісн.) | dynamic | 7.3 KB | 129.7 KB | 0.0% | 0.0% | 9.3 KB | 8.7 ms |
Як інтерпретувати результати
- Просте налаштування
use-intlпередає на 68.8 КБ більше JS на сторінку, ніж базовий додаток. - У режимі
dynamicuse-intlдосягає 119.4 КБ, але все одно зберігає 89.8% витоку сторінок. - Архітектурна різниця особливо помітна у розмірі компонентів: 76-87 КБ у
use-intlпроти 6-8 КБ в Intlayer. - Перемикання локалі відбувається у 2-4 рази швидше з Intlayer (3 мс проти 7-21 мс).
Повна таблиця у звіті бенчмарку TanStack Start.
Чому виникає різниця? Централізовані каталоги проти скомпільованих словників

next-intl слідує класичній моделі: один JSON для кожної мови, завантажується в getRequestConfig, передається в NextIntlClientProvider і зчитується через t("namespace.key").
Скопіюйте код у буфер обміну
Runtime не може передбачити, які саме ключі знадобляться сторінці, тому відправка всього каталогу є єдиним безпечним варіантом.
Ціна недосягнення цієї мети зростає відразу по двох осях, сторінки та локалі:

Intlayer змінює цей підхід. Контент декларується безпосередньо поруч із компонентом:
Скопіюйте код у буфер обміну
Під час збирання компілятор визначає, який компонент імпортує конкретний словник, і пакує тільки ці словники для активної локалі.
Щоб отримати показники рядкаdynamic, встановітьdictionary.importMode: 'dynamic'уintlayer.config.ts. Дивіться документацію з оптимізації бандла.
Досвід розробника
Клієнтський компонент
Скопіюйте код у буфер обміну
Скопіюйте код у буфер обміну
Не забудьте включити простір іменcounterу повідомлення, що передаються доNextIntlClientProviderна кожній сторінці, яка рендерить цей компонент.
Скопіюйте код у буфер обміну
Скопіюйте код у буфер обміну
На сторінці нічого не потрібно реєструвати: компонент приносить власний вміст.
Синхронні серверні компоненти
Елементи дизайн-системи (навігаційні панелі, підвали, картки) часто є серверними компонентами, що відображаються всередині клієнтських компонентів, тому вони не можуть бути async.
Скопіюйте код у буфер обміну
Сторінка повинна виконати await getTranslations("counter") та await getFormatter(), а потім передати результати як пропси. Компонент більше не є автономним.
Скопіюйте код у буфер обміну
Метадані
Скопіюйте код у буфер обміну
Скопіюйте код у буфер обміну
Збережіть API next-intl, отримайте оптимізований вихід Intlayer
Вам не потрібно переписувати компоненти, щоб отримати наведені вище результати продуктивності. Пакет @intlayer/next-intl є сумісним адаптером: він зберігає useTranslations, getTranslations, useFormatter, t.rich() та множинні форми ICU, обслуговуючи їх зі словників, скомпільованих компілятором Intlayer.
Скопіюйте код у буфер обміну
У бенчмарку сумісна збірка того самого додатка зменшила розмір сторінки з 153.6 КБ до 147.5 КБ, розмір компонентів з 21.8 КБ до 8.1 КБ, а витік сторінки знизився з ~90% до 0% без внесення змін у код самого додатка. Ваші наявні файли messages/{locale}.json можуть залишатися основним джерелом даних завдяки плагіну синхронізації JSON.
Дивіться посібник із міграції з next-intl для отримання покрокових інструкцій.
Що і коли обрати?
Вам потрібен стандарт екосистеми для Next.js, ви покладаєтеся на ICU MessageFormat, ваш додаток невеликий або середнього розміру, або ви інтегруєтеся з платформою перекладу (Crowdin, Phrase, Lokalise...), яка очікує централізований JSON. Заплануйте час на поділ каталогів на простори імен і вибір повідомлень через pick() на кожній сторінці, якщо важлива продуктивність.
Вам потрібен контент з областю видимості компонента, суворий TypeScript, помилки відсутніх ключів на етапі збірки, автоматичний tree-shaking та ліниве завантаження, синхронні серверні компоненти та вбудовані інструменти редагування (Візуальний редактор, CMS, ШІ-переклад, MCP-сервер). Особливо актуально для великих модульних кодових баз та дизайн-систем.
Ви вже використовуєте next-intl і хочете отримати переваги в розмірі бандла без повного переписування. Адаптер сумісності зберігає ваші імпорти та файл messages/{locale}.json як єдине джерело правди. Порівняно пліч-о-пліч у next-intl проти @intlayer/next-intl.
Часті запитання
Не під час рендерингу. Різниця полягає в тому, що надсилається клієнту: next-intl додає +12.6 KB gzip рантайму на кожній сторінці і в стандартних конфігураціях надсилає ~90% рядків чужих сторінок з кожною сторінкою. Перемикання мови та гідратація порівнянні в Next.js (15-18 мс); в TanStack Start use-intl займає 7-21 мс проти 3-4 мс у Intlayer.
Так, з конфігурацією scoped-dynamic: розділіть messages/{locale}.json на простори імен для кожного маршруту, потім використовуйте pick(messages, [...]) на кожній сторінці і підтримуйте це зіставлення правильним у міру переміщення компонентів. Рядки scoped-* бенчмарку якраз відображають цю роботу. Intlayer досягає 0% за замовчуванням без цього, оскільки компілятор ізолює контент по компонентах. Див. оптимізація бандла.
Ні. @intlayer/next-intl зберігає useTranslations, getTranslations, useFormatter, t.rich(), множинні форми ICU та помічники навігації, надаючи їх зі скомпільованих словників. Лише один рядок плагіна в next.config.ts. Покроково в посібнику з міграції next-intl.
Нативна підтримка ICU знаходиться в розробці. Адаптери сумісності (@intlayer/next-intl, @intlayer/use-intl) повністю підтримують ICU: множинні форми, select, selectordinal, # та {ts, date, long} обробляються резолвером ICU від Intlayer. Докладніше читайте в формат повідомлень ICU.
Так. Плагін синхронізації JSON читає їх, розбиває ключі верхнього рівня на словники та перезаписує переклади в ті самі файли під час оновлення через CLI або CMS. Робочий процес ваших перекладачів не змінюється.
Схожі порівняння
Той самий бенчмарк, інші бібліотеки:
Більше про next-intl:
Довідкова документація:
Щоб зрозуміти, звідки взялися ці бібліотеки, прочитайте історію i18n у JavaScript.
Зірки GitHub
Зірки на GitHub є важливим показником популярності проєкту, довіри спільноти та його довгострокової актуальності.
Активність комітів
Зірки показують популярність. Коміти показують, скільки роботи вкладено в проєкт. На момент написання Intlayer має близько 7 500 комітів: більше, ніж більшість порівнюваних тут бібліотек, і приблизно в 5 разів більше, ніж next-intl чи next-i18next.
- amannn/next-intl
- aymericzip/intlayer
Коміти в основній гілці, джерело: GitHub API.
Intlayer це монорепозиторій, тож до підрахунку входять усі пакети для фреймворків, CLI та документація. Сприймайте коміти як показник активності, а не якості.
Завантаження npm
- next-intl
- next-intlayer
Джерело: API завантажень реєстру npm.
Кількість завантажень винагороджує найстаріші рішення, а не найкращі. Бібліотеку, випущену багато років тому, досі встановлює кожен проєкт, що обрав її тоді, кожен запуск CI і кожен пакет, який від неї залежить. Ця цифра вимірює інерцію, а не свідомий вибір.
ШІ-асистенти посилюють цей ефект. next-intl, i18next і vue-i18n трапляються всюди в коді, на якому їх навчали, тож вони пропонують їх за замовчуванням, не порівнюючи альтернатив. Кожна підказка додає завантажень, які живлять наступну підказку. Порівнюйте за бенчмарком, а не за кількістю завантажень.
Висновок
next-intl - це надійна, перевірена часом бібліотека, і бенчмарк підтверджує, що вона залишається хорошим вибором для Next.js. Проте централізована модель каталогів перекладає всю оптимізацію на розробника: стандартне налаштування призводить до витоку близько 90% вмісту інших сторінок, а сам runtime коштує +12.6 КБ gzip на кожній сторінці.
Intlayer переносить усю цю роботу до компілятора. Словники для кожного компонента, ліниве завантаження для кожної мови та очищення невикористаного контенту стають автоматичними результатами збирання. Результат на тому ж додатку: +0.3 КБ на сторінку, 0% витоку, компоненти втричі менші, а перемикання мови у 2-4 рази швидше на TanStack Start.
Усі вихідні дані, тестові додатки та скрипти доступні у репозиторії Benchmark Bloom.
Зверніться до документа 'Чому Intlayer?' для отримання детальнішої інформації.
Коментарі
Поки що немає коментарів. Будьте першим, хто поділиться своїми думками.
