Управление размером кэша

Размер кэша в RTK Query определяет, сколько времени и при каких условиях данные, полученные из запроса, сохраняются в памяти Redux store. Это один из ключевых механизмов оптимизации, влияющий на количество сетевых запросов, скорость отклика интерфейса и поведение приложения при повторных обращениях к одним и тем же данным.

Кэш в RTK Query не является статической структурой. Он управляется через жизненный цикл подписок на данные и через параметры конфигурации, связанные с очисткой неиспользуемых записей. Основной принцип заключается в том, что данные сохраняются до тех пор, пока они считаются «актуально используемыми» хотя бы одним компонентом или подпиской.


Основной параметр управления размером кэша: keepUnusedDataFor

Ключевым инструментом регулирования размера кэша выступает параметр keepUnusedDataFor, задаваемый в createApi или на уровне отдельных endpoint’ов.

T_{cache} = T_{unsubscribed} + keepUnusedDataFor

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

Поведение механизма

  1. Компонент инициирует запрос через RTK Query.
  2. Данные попадают в кэш и становятся доступными для повторного использования.
  3. Когда последний компонент, использующий эти данные, размонтируется, начинается отсчет времени.
  4. По истечении keepUnusedDataFor запись удаляется из кэша.

Значение по умолчанию — 60 секунд, что обеспечивает баланс между повторным использованием данных и освобождением памяти.


Связь размера кэша с подписками

RTK Query использует модель подписок, где каждая активная подписка удерживает данные в памяти.

Влияние количества подписок

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

Таким образом, размер кэша фактически динамически определяется числом активных подписок, а не количеством запросов.


Разделение кэша по аргументам запроса

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

Пример:

  • getUsers() → 1 запись
  • getUsers({ page: 1 }) → отдельная запись
  • getUsers({ page: 2 }) → еще одна запись

N_{cache} = _{i=1}^{n} Q_i

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

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


Влияние мутаций на размер кэша

Мутации (useMutation) напрямую не увеличивают размер кэша в классическом смысле, но влияют на него косвенно через механизмы инвалидации.

После выполнения мутации:

  • могут быть помечены устаревшими определенные tags
  • связанные query-запросы будут перезапрошены
  • в кэше могут появляться новые записи вместо удаленных

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


Управление очисткой кэша через refetch и forceRefetch

Размер кэша также зависит от стратегии повторной загрузки данных.

refetchOnMountOrArgChange

Если включен этот параметр:

  • каждый новый монтирующийся компонент может инициировать новый запрос
  • кэш может временно расширяться до завершения дедупликации

forceRefetch

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


Дедупликация и её влияние на кэш

RTK Query выполняет дедупликацию запросов:

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

Это критический механизм, предотвращающий неконтролируемый рост кэша при частых повторных вызовах одного endpoint.

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


Практика настройки keepUnusedDataFor

Типовые значения:

Короткоживущий кэш (интенсивно меняющиеся данные)

  • 0–10 секунд
  • подходит для live-данных, чатов, мониторинга

Средний кэш (основной сценарий)

  • 30–120 секунд
  • оптимален для большинства CRUD-интерфейсов

Долгоживущий кэш (редко изменяемые данные)

  • 5–60 минут
  • справочники, настройки, статические списки

Выбор значения напрямую влияет на объем памяти, занимаемый Redux store.


Кэш и память браузера

RTK Query хранит кэш в памяти JavaScript, что означает:

  • рост кэша увеличивает потребление RAM
  • нет автоматического выхода за пределы памяти
  • при большом количестве уникальных запросов возможны утечки производительности

Особенно это заметно в SPA с длительной сессией и большим количеством фильтров и страниц.


Очистка всего кэша через resetApiState

Полный сброс кэша возможен через api.util.resetApiState().

Последствия:

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

Используется в сценариях:

  • выход пользователя
  • смена tenant’а
  • полная переинициализация приложения

Оптимизация роста кэша

Контроль размера кэша достигается сочетанием нескольких подходов:

  • ограничение количества уникальных аргументов запросов
  • использование нормализации параметров (например, объединение фильтров)
  • настройка keepUnusedDataFor
  • предотвращение избыточных refetch-запросов
  • применение тегов для управляемой инвалидации вместо частых повторных запросов

Влияние архитектуры приложения на размер кэша

Архитектурные решения напрямую определяют поведение кэша:

  • глубоко параметризованные endpoint’ы увеличивают количество записей
  • отсутствие стандартизации фильтров приводит к дублированию данных
  • повторное использование селекторов снижает нагрузку на кэш
  • разделение API на множество slice может усложнить контроль памяти

RTK Query эффективно работает только при предсказуемой структуре запросов и контролируемом разнообразии параметров.


Динамическое поведение кэша при длительной работе приложения

При длительной сессии наблюдается следующий цикл:

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

Баланс между накоплением и очисткой определяет фактический размер кэша в любой момент времени.