LocalStorage ограничения

LocalStorage представляет собой синхронное хранилище данных в браузере, предназначенное для сохранения простых пар ключ–значение. Несмотря на удобство использования, его архитектура накладывает ряд существенных ограничений, которые критичны при разработке приложений с использованием Mapbox GL JS и других клиентских библиотек, работающих с картографическими данными, стилями и пользовательским состоянием интерфейса.


Ограничение по объёму данных

Одним из ключевых факторов является ограничение на общий размер хранилища. В большинстве браузеров доступный объём варьируется в пределах 5–10 МБ на один origin (домен + протокол + порт). Это значение не фиксировано стандартом и зависит от реализации:

  • Chrome: около 10 МБ на origin
  • Firefox: около 10 МБ на origin
  • Safari: может быть меньше, особенно в режиме приватного просмотра
  • Mobile-браузеры: часто более агрессивные ограничения

При работе с Mapbox GL JS это ограничение быстро становится критичным, если попытаться хранить:

  • кэш пользовательских стилей карт (JSON-структуры)
  • состояния слоёв и фильтров
  • большие объекты конфигурации интерфейса
  • сериализованные геоданные (GeoJSON)

Даже умеренно сложный стиль Mapbox может занимать сотни килобайт, а несколько сохранённых конфигураций легко приближают приложение к лимиту.


Синхронная природа выполнения

LocalStorage работает синхронно, что означает блокировку основного потока выполнения JavaScript при каждом обращении:

  • чтение данных блокирует UI
  • запись данных блокирует UI
  • сериализация JSON дополнительно нагружает поток

В контексте Mapbox GL JS, где рендеринг карты зависит от стабильного FPS и непрерывного взаимодействия с WebGL, синхронные операции становятся источником:

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

Особенно заметно это при частых обновлениях состояния карты (например, сохранение позиции камеры после каждого moveend события).


Ограничение на тип данных

LocalStorage поддерживает исключительно строковые значения. Любые сложные структуры требуют сериализации:

localStorage.setItem("mapState", JSON.stringify(state));

и последующей десериализации:

const state = JSON.parse(localStorage.getItem("mapState"));

Это создаёт дополнительные проблемы:

  • накладные расходы на JSON.stringify / JSON.parse
  • риск ошибок при несовместимости схем данных
  • невозможность частичного обновления структуры без полной перезаписи
  • потеря производительности на больших объектах (например, GeoJSON)

Для Mapbox GL JS это особенно чувствительно при работе с большими наборами геоданных или стилями, содержащими десятки слоёв.


Отсутствие индексации и запросов

LocalStorage не предоставляет механизмов поиска или индексации данных. Доступ осуществляется только по ключу:

localStorage.getItem("key");

Это ограничивает архитектурные подходы:

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

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


Ограничения безопасности и изоляции

Данные LocalStorage доступны любому JavaScript-коду, выполняющемуся в рамках одного origin. Это создаёт следующие риски:

  • уязвимость к XSS-атакам
  • возможность кражи токенов доступа, если они сохранены некорректно
  • отсутствие разграничения прав доступа между скриптами

В приложениях с Mapbox GL JS это особенно критично, поскольку часто используются:

  • публичные и приватные access token
  • пользовательские настройки отображения карты
  • геопривязанные данные

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


Поведение при переполнении

Когда квота LocalStorage исчерпана, браузер может:

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

Это создаёт нестабильность в приложениях, где сохранение состояния карты происходит автоматически. Без обработки ошибок возможны:

  • потеря пользовательских настроек
  • неконсистентное состояние интерфейса
  • сбои при инициализации карты после перезагрузки

Зависимость от режима браузера

Поведение LocalStorage различается в зависимости от среды выполнения:

  • Приватный режим: данные могут не сохраняться или удаляться после сессии
  • iOS Safari: возможна очистка при нехватке памяти
  • WebView (мобильные приложения): нестабильные квоты и ограничения
  • Enterprise-политики: могут полностью отключать доступ

Для картографических приложений это приводит к невозможности гарантировать сохранение пользовательских слоёв и настроек Mapbox между сессиями.


Ограничения конкурентного доступа

LocalStorage не предназначен для конкурентных операций:

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

При работе с несколькими вкладками Mapbox-приложения возможны ситуации:

  • перезапись состояния камеры карты
  • конфликт пользовательских настроек слоёв
  • рассинхронизация фильтров и источников данных

Отсутствие версионирования данных

LocalStorage не поддерживает версионирование или миграции схем. При изменении структуры данных приложения:

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

В контексте Mapbox GL JS это проявляется при обновлении структуры:

  • стилей карты (style specification)
  • конфигураций источников (sources)
  • пользовательских слоёв

Без дополнительной логики приложение может некорректно интерпретировать сохранённые данные.


Альтернативные подходы хранения данных

При разработке приложений с интенсивным использованием Mapbox GL JS LocalStorage часто заменяется или дополняется более устойчивыми механизмами:

  • IndexedDB для больших объёмов данных и асинхронного доступа
  • Cache Storage для ресурсов (тайлы, стили)
  • серверное хранение пользовательских конфигураций
  • sessionStorage для временного состояния интерфейса

IndexedDB особенно важен в картографических приложениях, так как позволяет:

  • хранить GeoJSON и тайлы без строгого лимита в 5–10 МБ
  • выполнять асинхронные операции без блокировки UI
  • структурировать данные в виде объектов и индексов

Практическое влияние на архитектуру Mapbox GL JS приложений

Ограничения LocalStorage напрямую влияют на проектирование клиентской части:

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

При грамотной архитектуре LocalStorage используется только для:

  • небольших пользовательских предпочтений интерфейса
  • флагов состояния (включено/выключено)
  • минимальных параметров отображения карты