Автор:
    Дата створення:2026-04-20Останнє оновлення:2026-09-27

    Бібліотеки i18n для Solid - Звіт про бенчмарк 2026

    Ця сторінка є звітом про бенчмарк рішень i18n на Solid.

    Зміст

    Інтерактивний бенчмарк

    Метрика

    Динамічне завантаження JSON

    Ледаче завантаження перекладів під час виконання

    Обмежений JSON (простори імен)

    Простори імен перекладу для кожної сторінки

    Що це за метрика?

    Загальний стиснений у gzip розмір пакета бібліотеки інтернаціоналізації. Він включає лише провайдер та логіку отримання контенту після tree-shaking та мініфікації.

    Чому це важливо?

    Менший розмір бібліотеки зменшує початкове завантаження JavaScript, що призводить до швидшого завантаження та виконання на клієнті.

    Перегляд як

    Посилання на результати:

    Вступ

    Рішення для інтернаціоналізації є одними з найважчих залежностей у додатку Solid. Основний ризик полягає у відправці непотрібного контенту: перекладів для інших сторінок та інших локалей у бандлі одного маршруту.

    З ростом вашого додатка ця проблема може швидко збільшити обсяг JavaScript, що надсилається клієнту, і сповільнити навігацію.

    На практиці, для найменш оптимізованих реалізацій, інтернаціоналізована сторінка може виявитися в кілька разів важчою, ніж версія без i18n.

    Інший вплив стосується досвіду розробника (DX): як ви оголошуєте контент, типи, організацію просторів імен, динамічне завантаження та реактивність при зміні локалі.

    Щоб зрозуміти, звідки взялися ці бібліотеки, прочитайте історію i18n у JavaScript.

    TL;DR

    • Intlayer: Рекомендований вибір для професійних додатків Solid, які потребують розширених функцій та оптимізації (v9.5.10).
    • @solid-primitives/i18n: Відмінна легка альтернатива для простих проєктів, хоча їй бракує розширених функцій, таких як lazy loading.
    • solid-i18next: Стандартний, але важкий варіант (~3.5 рази більше за Intlayer) з тими ж недоліками, що і React i18next.
    • Tolgee: Багатофункціональна платформа перекладів, але досить важка (~12.7 КБ, приблизно в 3.0× важча за Intlayer), не має рідних примітивів для Solid (спирається на @tolgee/web) та демонструє значний витік між сторінками у статичних конфігураціях (90% витоку сторінок).
    • Paraglide: Інноваційний підхід, але складний DX та проблеми з tree-shaking у деяких конфігураціях.

    Протестуйте свій додаток

    Щоб швидко виявити проблеми з витоком i18n, ви можете спробувати безкоштовний i18n SEO-сканер.

    Проблема

    Два важелі є важливими для обмеження вартості багатомовного додатка:

    • Розділіть контент за сторінками / просторами імен, щоб не завантажувати цілі словники, коли вони не потрібні.
    • Завантажуйте потрібну локаль динамічно, тільки коли це необхідно.

    Розуміння технічних обмежень цих підходів:

    Динамічне завантаження

    Без динамічного завантаження більшість рішень зберігають повідомлення в пам'яті з першого рендеру, що додає значне навантаження для додатків з багатьма маршрутами та локалями.

    З динамічним завантаженням ви приймаєте компроміс: менше початкового JS, але іноді додатковий запит при зміні мови.

    Поділ контенту (Splitting)

    Синтаксис, побудований навколо t('a.b.c'), дуже зручний, але часто заохочує зберігати великі JSON-об'єкти під час виконання. Ця модель ускладнює tree-shaking, якщо бібліотека не пропонує реальної стратегії поділу на сторінки.

    Методологія дослідження

    Для цього бенчмарку ми порівняли наступні бібліотеки:

    Фреймворк - Solid з багатомовним додатком із 10 сторінок і 10 мов.

    Ми порівняли чотири стратегії завантаження:

    СтратегіяБез просторів імен (глобально)З просторами імен (scoped)
    Статичне завантаженняStatic: Все в пам'яті при запуску.Scoped static: Розділено за просторами імен; все завантажено при запуску.
    Динамічне завантаженняDynamic: Завантаження за запитом для кожної локалі.Scoped dynamic: Детальне завантаження за простором імен та локаллю.

    Підсумок стратегій

    • Static: Просто; немає затримки мережі після початкового завантаження. Мінус: великий розмір бандла.
    • Dynamic: Зменшує початкову вагу (lazy-loading). Ідеально, коли у вас багато локалей.
    • Scoped static: Зберігає код організованим (логічне розділення) без складних додаткових мережевих запитів.
    • Scoped dynamic: Найкращий підхід для code splitting та продуктивності. Мінімізує пам'ять, завантажуючи лише те, що потрібно поточному перегляду та активній локалі.

    Що я вимірював:

    Я запустив одну й ту саму багатомовну програму в реальному браузері для кожного стеку, а потім записав, що насправді з'явилося на мережі та як довго тривав процес. Розміри наводяться після звичайного стиснення веб-вмісту, оскільки це ближче до того, що люди завантажують, ніж необроблене джерельне числення.

    • Розмір бібліотеки інтернаціоналізації: Після bundling, tree-shaking та мініфікації, розмір бібліотеки i18n це розмір providers + hooks/primitives кода в порожній компоненті. Він не включає завантаження файлів перекладу. Це відповідає на питання про вартість бібліотеки до того, як ваш вміст потрапить у картину.

    • JavaScript на сторінку: Для кожного маршруту бенчмарку, скільки скрипту браузер витягує для цього відвідування, усереднено по сторінках у наборі (та по мовах, де звіт їх об'єднує). Важкі сторінки, повільні сторінки.

    • Утечка з інших мов: Це вміст однієї й тієї ж сторінки, але іншою мовою, який по помилці був би завантажений у проаудитовану сторінку. Цей вміст непотрібний і його слід уникати. (напр. вміст сторінки /fr/about в bundle сторінки /en/about)

    • Утечка з інших маршрутів: Та сама ідея для інших екранів у додатку: чи їхний вміст їде разом, коли ви відкрили лише одну сторінку. (напр. вміст сторінки /en/about в bundle сторінки /en/contact). Висока оцінка вказує на слабке розділення або занадто широкі bundle.

    • Середній розмір bundle компоненти: Звичайні елементи інтерфейсу вимірюються один за одним замість того, щоб приховуватися всередину одного гігантського числа програми. Це показує, чи інтернаціоналізація тихо збільшує повсякденні компоненти. Наприклад, якщо ваша компонента повторно рендерується, вона завантажить всі ці дані з пам'яті. Прикріплення гігантської JSON до будь-якої компоненти це як підключення великого сховища невикористаних даних, що сповільнить роботу ваших компонент.

    • Адаптивність перемикання мови: Я перемикаю мову за допомогою контролю програми й розраховую, як довго це займає, поки сторінка явно не переключиться, що помітить відвідувач, а не мікрокрок у лабораторії.

    • Робота рендерингу після зміни мови: Вужчий наступний крок: скільки зусиль знадобилося інтерфейсу для перепалітури на нову мову, коли перемикання в польоті. Корисно, коли «відчутний» час і вартість фреймворку розходяться.

    • Час завантаження початкової сторінки: Від навігації до браузера, який вважає сторінку повністю завантаженою для сценаріїв, які я тестував. Добре для порівняння холодних запусків.

    • Час гідратації: Коли програма це виявляє, скільки часу клієнт витрачає на перетворення серверної HTML у щось, на що ви можете насправді клікнути. Тире в таблицях означає, що ця реалізація не надала надійної цифри гідратації в цьому бенчмарку.

    Зірки на GitHub

    Зірки на GitHub є потужним індикатором популярності проекту, довіри спільноти та довгострокової актуальності. Хоча вони не є прямим показником технічної якості, вони відображають, скільки розробників вважають проект корисним, стежать за його розвитком і, ймовірно, впровадять його. Для оцінки цінності проекту зірки допомагають порівняти інтерес до альтернатив і дають уявлення про зростання екосистеми.

    Star History Chart

    Активність комітів

    Зірки показують популярність. Коміти показують, скільки роботи вкладено в проєкт. На момент написання Intlayer має близько 7 500 комітів: більше, ніж більшість порівнюваних тут бібліотек, і приблизно в 5 разів більше, ніж next-intl чи next-i18next.

    • solidjs-community/solid-primitives
    • mbarzda/solid-i18next
    • opral/paraglide-js
    • tolgee/tolgee-js
    • aymericzip/intlayer

    Коміти в основній гілці, джерело: GitHub API.

    Intlayer це монорепозиторій, тож до підрахунку входять усі пакети для фреймворків, CLI та документація. Сприймайте коміти як показник активності, а не якості.

    Завантаження npm

    • @solid-primitives/i18n
    • @mbarzda/solid-i18next
    • @inlang/paraglide-js
    • @tolgee/web
    • solid-intlayer

    Джерело: API завантажень реєстру npm.

    Кількість завантажень винагороджує найстаріші рішення, а не найкращі. Бібліотеку, випущену багато років тому, досі встановлює кожен проєкт, що обрав її тоді, кожен запуск CI і кожен пакет, який від неї залежить. Ця цифра вимірює інерцію, а не свідомий вибір.

    ШІ-асистенти посилюють цей ефект. next-intl, i18next і vue-i18n трапляються всюди в коді, на якому їх навчали, тож вони пропонують їх за замовчуванням, не порівнюючи альтернатив. Кожна підказка додає завантажень, які живлять наступну підказку. Порівнюйте за бенчмарком, а не за кількістю завантажень.

    Результати детально

    1 - Рішення, яких слід уникати

    В екосистемі Solid немає очевидних рішень, яких слід уникати.

    2 - Прийнятні рішення

    (solid-i18next) (i18next@26.0.8):

    solid-i18next, ймовірно, є найпопулярнішим варіантом, оскільки він був одним із перших, хто задовольнив потреби i18n у JavaScript-додатках. Він також має широкий набір плагінів спільноти для конкретних проблем.

    Пакет важкий (~14.9kb, що приблизно в 3.5 рази більше за solid-intlayer).

    Тим не менш, він має ті ж основні недоліки, що і стеки, побудовані на t('a.b.c'): оптимізація можлива, але забирає багато часу, а великі проєкти ризикують поганими практиками (простори імен + динамічне завантаження + типи).

    (@solid-primitives/i18n) (@solid-primitives/i18n@2.2.1):

    Solid primitive надзвичайно легкий і ефективний. Я рекомендую це рішення для легких проєктів, але в ньому може швидко не вистачити функцій для професійних рішень, що включають управління кукі, перенаправлення проксі, форматери тощо. Йому також не вистачає lazy loading та скоупінгу просторів імен для оптимізації розміру сторінки.

    (Tolgee) (@tolgee/web@7.2.0):

    Tolgee пропонує повнофункціональну платформу керування перекладами з можливостями редагування in-context.

    Для Solid наразі немає офіційного нативного адаптера (такого як @tolgee/solid), тому розробникам доводиться інтегрувати бібліотеку через @tolgee/web із кастомними сигналами.

    Пакет досить важкий (~12.7 КБ, що приблизно в 3.0× більше за solid-intlayer).

    Через відсутність механізму гранулярного поділу за сторінками у Solid усі переклади завантажуються в пам'ять на старті у статичних конфігураціях. Це призводить до значного витоку бандлу (44.5% витоку локалей, 90.0% витоку сторінок) та середнього розміру бандлу сторінки ~91.8 КБ (порівняно з ~35.4 КБ у Intlayer).

    Реактивність при зміні мови дуже швидка (0.6 мс), що чудово узгоджується з точковою реактивністю Solid, хоча накладні витрати на гідратацію вищі (~5.6 мс проти ~3.0 мс у Intlayer).

    (Paraglide) (@inlang/paraglide-js@2.25.1):

    Paraglide пропонує інноваційний, добре продуманий підхід. Незважаючи на це, у цьому бенчмарку деревоподібне шейкінг (tree-shaking), яке рекламує їхня компанія, не спрацювало для моєї реалізації. Робочий процес і DX також складніші за інші варіанти. Особисто я не прихильник того, щоб перегенерувати файли JS перед кожним пушем, що створює постійний ризик конфліктів при злитті через PR. Нарешті, у порівнянні з іншими рішеннями, Paraglide не використовує стор (наприклад, Solid signal) для отримання поточної локалі для рендерингу контенту. Для кожного розібраного вузла він запитуватиме локаль з localStorage / cookie тощо. Це призводить до виконання непотрібної логіки, яка впливає на реактивність компонентів.

    3 - Рекомендації

    (Intlayer) (solid-intlayer@9.5.10):

    Я не буду особисто оцінювати solid-intlayer заради об'єктивності, оскільки це моє власне рішення.

    Особиста примітка

    Ця примітка є особистою і не впливає на результати бенчмарку. Тим не менш, у світі i18n часто можна побачити консенсус щодо патерну на кшталт const t = useTranslation('xx') + <>{t('xx.xx')}</> для перекладеного контенту.

    У додатках Solid впорскування функції як JSX.Element, на мій погляд, є антипатерном. Це також додає зайву складність та накладні витрати на виконання JavaScript (навіть якщо це ледь помітно).