Минификация данных

Минификация данных в Globalize связана с уменьшением объёма локализационных ресурсов (CLDR-данных) и пользовательских сообщений, которые попадают в итоговую сборку приложения. Библиотека Globalize опирается на стандартизированные данные Unicode CLDR (Common Locale Data Repository), которые включают числовые форматы, валюты, правила плюрализации, форматы дат и времени, а также локализованные строки. Эти данные в исходном виде достаточно объёмные, и их необдуманное подключение приводит к значительному увеличению размера JavaScript-бандла.

CLDR-структура изначально проектировалась как универсальный источник локализационной информации для всех языков мира. В результате:

  • поддерживаются сотни локалей;
  • каждая локаль содержит множество категорий данных;
  • часть данных дублируется между локалями;
  • правила плюрализации могут содержать десятки условий;
  • числовые и валютные форматы включают альтернативные представления.

Globalize использует подмножество этих данных, но при неправильной конфигурации приложения в сборку попадает весь пакет локалей или значительная его часть. Это особенно критично в браузерных приложениях, где каждый килобайт влияет на скорость загрузки.

Принцип минимального набора локализационных данных

Минификация в контексте Globalize строится на принципе подключения только используемых сегментов CLDR. Вместо загрузки полной базы данных используется выборочная загрузка:

  • только нужные локали (например, en, ru);
  • только используемые типы данных (numbers, dates, currencies);
  • только необходимые supplemental-данные (plurals, time zones).

CLDR разбит на модули, и Globalize позволяет загружать их независимо. Это создаёт основу для агрессивной оптимизации.

Разделение CLDR-данных на модули

CLDR-данные в Globalize условно делятся на следующие категории:

  • supplemental — универсальные правила (плюрализация, вероятности, метаданные);
  • main — данные конкретных локалей;
  • segments — вспомогательные структуры форматирования.

Минификация заключается в исключении ненужных категорий и локалей. Например, если приложение не использует валютное форматирование, модуль currencyData может быть полностью исключён.

Tree-shaking и статическая сборка

Современные сборщики (Webpack, Rollup, Vite) позволяют применять tree-shaking к Globalize-модулям, однако эффективность зависит от структуры импортов.

Правильный подход:

  • импортировать только используемые функции;
  • избегать глобального подключения globalize с полным набором методов;
  • разделять код по локалям.

Пример избыточного подключения:

import Globalize from "globalize";

Такой импорт часто приводит к включению большого количества зависимостей.

Оптимизированный вариант:

import Globalize from "globalize/dist/globalize";
import "globalize/dist/globalize/number";
import "globalize/dist/globalize/currency";

Каждый модуль подключается отдельно, что позволяет сборщику исключать неиспользуемые части.

Минификация CLDR через выборочную загрузку

CLDR-данные обычно подключаются явно:

import likelySubtags from "cldr-data/supplemental/likelySubtags";
import plurals from "cldr-data/supplemental/plurals";
import timeData from "cldr-data/supplemental/timeData";

import ruNumbers from "cldr-data/main/ru/numbers";
import ruCurrencies from "cldr-data/main/ru/currencies";
import ruCaGregorian from "cldr-data/main/ru/ca-gregorian";

Такой подход позволяет контролировать состав данных на уровне модулей.

Ключевой принцип минификации — исключение любых main/*, которые не используются в интерфейсе. Если приложение поддерживает только одну локаль, остальные полностью удаляются из сборки.

Сжатие сообщений и форматтеров

Globalize поддерживает форматирование сообщений через ICU-подобный синтаксис. Эти сообщения также могут стать источником избыточности.

Пример неоптимального набора сообщений:

Globalize.loadMessages({
  ru: {
    greeting: "Привет",
    farewell: "До свидания",
    dateFormatLong: "EEEE, d MMMM yyyy"
  }
});

При масштабировании приложения количество сообщений растёт, и без оптимизации они начинают занимать значительный объём.

Минификация сообщений достигается за счёт:

  • удаления неиспользуемых ключей;
  • разделения сообщений по модулям (lazy-loading);
  • хранения сообщений вне основного бандла.

Lazy-loading локалей

Одним из наиболее эффективных методов уменьшения размера начальной загрузки является отложенная загрузка локализационных данных.

Структура приложения:

  • базовый бандл содержит только en;
  • дополнительные локали подгружаются по требованию;
  • Globalize инициализируется динамически.

Пример динамического подключения:

async function loadLocale(locale) {
  const cldrData = await import(`cldr-data/main/${locale}/numbers`);
  Globalize.load(cldrData);
}

Такой подход снижает размер initial bundle, особенно в приложениях с множеством языков.

Минификация через серверную агрегацию данных

На уровне сборки можно заранее агрегировать минимальный набор CLDR:

  • генерация кастомного JSON;
  • удаление неиспользуемых разделов;
  • объединение только нужных локалей.

Это особенно полезно в SSR-приложениях, где клиенту передаётся уже подготовленный минимальный набор данных.

Оптимизация форматтеров

Каждый форматтер Globalize (number, date, currency) требует своих зависимостей. Если используются только числа, подключение дат и валют становится избыточным.

Пример:

import "globalize/dist/globalize/number";

Если добавить date, размер увеличится за счёт правил календарей и временных зон.

Минификация достигается строгим разделением:

  • number — только числовые форматы;
  • date — только форматирование дат;
  • currency — только валютные представления.

Контроль зависимости от Unicode CLDR версии

Разные версии CLDR имеют различный объём данных. Обновления часто добавляют новые локали и расширяют правила. Это влияет на размер итогового бандла.

При оптимизации важно:

  • фиксировать версию CLDR;
  • избегать автоматического подтягивания всей базы;
  • пересобирать только нужные сегменты при обновлении.

Влияние минификации на производительность

Сокращение данных напрямую влияет на:

  • скорость загрузки JavaScript;
  • время инициализации Globalize;
  • объем памяти в runtime;
  • скорость парсинга JSON.

Особенно критично это для мобильных устройств, где парсинг больших JSON-структур становится узким местом.

Сборка через Webpack и внешние плагины

Для управления CLDR часто используется дополнительная конфигурация сборщиков:

  • ограничение import context;
  • исключение ненужных языков через IgnorePlugin;
  • ручная настройка entry points для локалей.

Пример ограничения локалей:

new webpack.IgnorePlugin({
  resourceRegExp: /^cldr-data\/main\/(?!ru|en)/
});

Это гарантирует, что в сборку попадут только нужные языки.

Разделение runtime и data-слоя

Globalize можно разделить на два слоя:

  • runtime (логика форматирования);
  • data (CLDR-данные).

Минификация достигается за счёт независимой поставки data-слоя. Runtime остаётся стабильным, а данные могут обновляться или подгружаться отдельно.

Итоговая модель минимизации

Минимизированная конфигурация Globalize обычно включает:

  • одну или две локали;
  • ограниченный набор CLDR-модулей;
  • только используемые форматтеры;
  • разделённые сообщения;
  • динамическую подгрузку языков.

Такая модель позволяет снизить размер локализационного слоя с мегабайтов до десятков килобайт без потери функциональности.