Опции кеширования

Внутреннее кеширование загруженных ресурсов

i18next после инициализации формирует внутренний кэш загруженных переводов в памяти приложения. Все ресурсы, полученные через backend (HTTP, файловую систему или пользовательский загрузчик), сохраняются в структуре store.

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

Основные свойства поведения:

  • ресурсы хранятся в оперативной памяти до перезагрузки страницы или перезапуска Node.js-процесса

  • повторный вызов t() не инициирует повторную загрузку переводов

  • данные группируются по:

    • языку (lng)
    • namespace (ns)

Пример структуры хранения:

i18next.services.resourceStore.data = {
  en: {
    translation: {
      hello: "Hello"
    }
  },
  ru: {
    translation: {
      hello: "Привет"
    }
  }
}

Кеш в памяти не имеет встроенного TTL и очищается только вручную или при уничтожении экземпляра i18next.


Кеширование при использовании HTTP backend

При использовании i18next-http-backend ключевую роль играет механизм загрузки переводов по HTTP. Он опирается на стандартное кеширование браузера и сетевого уровня.

Базовая конфигурация:

import Backend from 'i18next-http-backend';

i18next.use(Backend).init({
  backend: {
    loadPath: '/locales/{{lng}}/{{ns}}.json'
  }
});

Поведение кеша на уровне браузера

Кеширование контролируется заголовками HTTP:

  • Cache-Control
  • ETag
  • Last-Modified

Если сервер возвращает корректные заголовки, браузер:

  • повторно использует файл переводов без запроса к серверу
  • делает conditional request (304 Not Modified)

Это снижает нагрузку на backend без участия i18next.


Опции контроля кеширования в HTTP backend

i18next-http-backend предоставляет дополнительные параметры, влияющие на повторное получение данных.

requestOptions

Позволяет управлять HTTP-запросами, включая заголовки кеширования:

backend: {
  loadPath: '/locales/{{lng}}/{{ns}}.json',
  requestOptions: {
    cache: 'force-cache'
  }
}

Использование зависит от окружения (fetch или xhr).


allowMultiLoading

Хотя напрямую не является кешем, влияет на количество запросов:

backend: {
  allowMultiLoading: true,
  loadPath: '/locales/{{lng}}/all.json'
}

Позволяет загружать несколько namespace за один запрос, уменьшая вероятность повторных сетевых обращений.


Кеширование в localStorage через сторонние backend-решения

Стандартный i18next не хранит переводы в persistent storage, но существует подход через localStorage-backend.

Пример использования i18next-localstorage-backend:

import LocalStorageBackend from 'i18next-localstorage-backend';

i18next.use(LocalStorageBackend).init({
  backend: {
    expirationTime: 7 * 24 * 60 * 60 * 1000,
    defaultVersion: '1.0',
    versions: {
      en: '1.0',
      ru: '1.0'
    }
  }
});

expirationTime

Определяет время жизни кеша в миллисекундах.

  • после истечения срока данные перезапрашиваются
  • позволяет реализовать TTL для переводов

versions

Используется для инвалидации кеша при изменении переводов.

  • изменение версии автоматически игнорирует старый кеш
  • применяется как хеш набора переводов

Кеширование языка пользователя

Плагин i18next-browser-languagedetector также использует кеширование, но другого типа — сохранение выбранного языка.

Основные опции:

import LanguageDetector from 'i18next-browser-languagedetector';

i18next.use(LanguageDetector).init({
  detection: {
    caches: ['localStorage', 'cookie']
  }
});

caches

Определяет, куда сохраняется выбранный язык:

  • localStorage
  • cookie
  • sessionStorage

Это не кеш переводов, но влияет на повторную инициализацию языка.


Механизм предотвращения повторной загрузки ресурсов

i18next использует внутреннюю защиту от дублей запросов.

При одновременной загрузке одного и того же ресурса:

  • создаётся один запрос
  • остальные подписываются на его результат
  • результат распространяется на всех подписчиков

Это предотвращает:

  • race condition при параллельной инициализации
  • дублирование HTTP-запросов

Кеширование при chained backend

i18next-chained-backend позволяет комбинировать несколько источников с приоритетами, например:

import ChainedBackend from 'i18next-chained-backend';
import HttpBackend from 'i18next-http-backend';
import LocalStorageBackend from 'i18next-localstorage-backend';

i18next.use(ChainedBackend).init({
  backend: {
    backends: [
      LocalStorageBackend,
      HttpBackend
    ],
    backendOptions: [
      {
        expirationTime: 24 * 60 * 60 * 1000
      },
      {
        loadPath: '/locales/{{lng}}/{{ns}}.json'
      }
    ]
  }
});

Логика кеширования

  1. проверяется localStorage
  2. при отсутствии или устаревании выполняется HTTP-загрузка
  3. результат сохраняется обратно в кеш

Инвалидация кеша

Инвалидация происходит по нескольким сценариям:

1. Изменение версии ресурсов

versions: {
  ru: '2.0'
}

Любое изменение версии приводит к игнорированию старых данных.


2. Истечение TTL (localStorage backend)

expirationTime: 86400000

После истечения времени данные считаются устаревшими.


3. Ручная очистка

Возможна через API браузера:

localStorage.removeItem('i18next_res_en_translation')

4. Перезапуск runtime (memory cache)

Очистка происходит автоматически при перезагрузке приложения.


Кеширование и стратегия загрузки ресурсов

На кеширование напрямую влияет стратегия load.

load: 'all'

Загружаются все варианты языка:

i18next.init({
  load: 'all'
});
  • увеличивает размер кеша
  • снижает количество сетевых запросов

load: 'currentOnly'

Загружается только текущая локаль:

  • минимальный кеш
  • частые обращения к backend при переключении языков

load: 'languageOnly'

Игнорируются региональные вариации:

  • en-USen
  • уменьшает количество кешируемых наборов

Preload и частичное кеширование

Опция preload позволяет заранее заполнить кеш:

i18next.init({
  preload: ['en', 'ru']
});

Эффект:

  • ресурсы загружаются до первого использования
  • исключаются задержки при переключении языков
  • увеличивается объём памяти, занятой кешем

Кеширование missing keys (косвенный эффект)

При включении saveMissing создаётся дополнительный поток данных, который может влиять на кеширование состояния:

i18next.init({
  saveMissing: true
});

Хотя это не кеш переводов, а механизм отправки отсутствующих ключей, он влияет на:

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

Поведение кеша в SSR (Node.js)

В серверном окружении кеширование имеет особенности:

  • отсутствует localStorage
  • используется только memory store
  • каждый запрос может создавать новый instance i18next

Для оптимизации применяются:

  • singleton instance i18next
  • shared resource store между запросами
  • предварительная загрузка переводов до обработки HTTP-запросов

Гибридные стратегии кеширования

Практически используемые схемы:

1. Memory + HTTP cache

  • быстрый доступ в рамках сессии
  • контроль через HTTP заголовки

2. localStorage + versioning + HTTP fallback

  • офлайн-доступ к переводам
  • контроль обновлений через версии

3. Preload + memory store

  • отсутствие задержек при переключении языков
  • повышенное потребление памяти

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

Кеширование напрямую влияет на:

  • скорость вызова t()
  • количество HTTP-запросов
  • время инициализации приложения
  • UX при смене языка

Наиболее критичный слой — сетевой, поэтому основная оптимизация достигается через:

  • HTTP cache headers
  • localStorage backend
  • предварительную загрузку языков