Intl API в JavaScript опирается на ICU (International Components for Unicode), который предоставляет данные локалей: правила форматирования дат, чисел, валют, склонений, сравнений строк. В браузерах поддержка часто встроена, но в Node.js и в старых окружениях возникает необходимость полифилов или дополнительных пакетов локалей. Это приводит к ключевой инженерной проблеме: росту размера бандла и влиянию на производительность загрузки.
Базовые объекты Intl:
Intl.DateTimeFormatIntl.NumberFormatIntl.CollatorIntl.PluralRulesIntl.RelativeTimeFormatIntl.ListFormatIntl.DisplayNamesКаждый из них зависит не только от кода реализации, но и от огромного набора локализационных данных:
Основная масса веса приходится не на JavaScript-код, а на JSON/CLDR-данные (Unicode Common Locale Data Repository).
В среде Node.js и некоторых сборках существует несколько режимов ICU:
Содержит ограниченный набор локалей (обычно английский + системные). Размер минимален, но поддержка локалей ограничена.
Содержит полный набор локалей ICU. Размер увеличивается на десятки мегабайт.
Использует ICU, установленный в системе. Поведение зависит от окружения, что снижает предсказуемость.
Разница между режимами критична: переход от small-icu к full-icu может увеличить бинарь Node.js и зависимые артефакты на десятки мегабайт.
В браузерах Intl обычно присутствует, но часто возникают ситуации:
Наиболее распространённые полифилы:
@formatjs/intlintl-messageformatintl-pluralrulesintl-relativetimeformatКаждый пакет может включать:
Главная проблема — локали.
Примерные категории роста:
Небольшой кодовый слой: несколько десятков килобайт после минификации.
Каждая локаль добавляет:
Рост: от сотен килобайт до нескольких мегабайт в зависимости от покрытия.
При подключении всех языков CLDR:
Ключевая стратегия оптимизации — разделение:
Локали загружаются динамически:
en, ru,
de, zhЭто уменьшает initial bundle, но увеличивает сложность runtime.
Современные сборщики позволяют импортировать только нужные части:
NumberFormatDateTimeFormatОднако эффективность tree-shaking ограничена, поскольку CLDR-данные часто не поддаются статическому анализу.
Рост размера полифилов влияет на три уровня:
Увеличение payload приводит к:
JSON-локали требуют значительного времени парсинга:
После загрузки:
Intl API сам по себе не является бесплатным по вычислениям.
Основные затраты:
new Intl.DateTimeFormat() и аналогичные вызовы:
Стоимость особенно заметна при частом создании объектов.
Оптимизация:
Каждый вызов:
На больших списках это становится заметной нагрузкой CPU.
Нативный Intl (в браузерах и full-icu Node.js) обычно:
Полифилы:
Разница по производительности:
Разные части Intl имеют разный вес:
Intl.NumberFormat (ограниченный набор локалей —
умеренный рост)Intl.RelativeTimeFormatIntl.PluralRulesIntl.DateTimeFormatIntl.CollatorIntl.DisplayNamesCollator особенно дорог из-за сложных правил сортировки
Unicode.
DisplayNames, если не требуетсяRelativeTimeFormat на упрощённые функцииМинус — потеря гибкости клиентского рендера.
Полифилы Intl влияют не только на runtime:
Особенно заметно при:
CLDR-данные хорошо кэшируются:
Но существует проблема:
В реальных системах Intl-полифилы часто становятся скрытым источником:
Особенно критично при: