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

В Mapbox GL JS кэширование представляет собой многослойную систему, в которой участвуют несколько уровней: браузерный HTTP-кэш, внутренний ресурсный кэш библиотеки, кэш тайлов, спрайтов и шрифтов (glyphs), а также дополнительные механизмы хранения при офлайн-сценариях. Такая архитектура необходима для обеспечения плавного рендеринга карт, минимизации сетевых запросов и снижения нагрузки на GPU и CPU.

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


HTTP-кэширование и заголовки ответов

Первый уровень оптимизации происходит на стороне браузера. Mapbox GL JS активно использует стандартные механизмы HTTP-кэширования:

  • Cache-Control
  • ETag
  • Last-Modified

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

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


Кэш тайлов (Tile Cache)

Тайлы — центральный элемент системы кэширования Mapbox GL JS. Они делятся на:

  • векторные тайлы (vector tiles)
  • растровые тайлы (raster tiles)
  • DEM/terrain тайлы (в современных стилях)

Каждый загруженный тайл сохраняется в памяти Mapbox GL JS и индексируется по ключу:

  • source ID
  • координаты z/x/y
  • версия стиля
  • параметры запроса (query parameters)

Механизм хранения

Внутренний кэш тайлов реализует LRU-подобную стратегию (least recently used). Это означает:

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

Важный аспект

При изменении стиля карта может переиспользовать тайлы, если:

  • совпадает источник (source)
  • не изменились параметры фильтрации
  • не изменилась схема тайлового URL

Кэш источников данных (Sources Cache)

Каждый источник (source) в Mapbox GL JS имеет собственный слой кэширования.

Например:

map.addSource('cities', {
  type: 'vector',
  url: 'mapbox://examples.city'
});

Для таких источников кэшируются:

  • список тайлов
  • метаданные источника
  • состояние загрузки (loaded / loading / aborted)

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


Кэш glyphs (шрифты)

Глифы используются для рендеринга текста на карте. Они загружаются пакетами в формате PBF и кэшируются на уровне:

  • диапазона символов
  • семейства шрифта
  • размера

URL шаблон обычно выглядит так:

/fonts/{fontstack}/{range}.pbf

Особенности кэширования glyphs

  • загружаются сегментами (ranges)
  • повторно используются между слоями текста
  • могут кешироваться даже при смене стиля, если используется тот же fontstack

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


Кэш спрайтов и изображений

Спрайты представляют собой набор иконок и графических элементов стиля.

Mapbox GL JS загружает:

  • sprite.json
  • sprite.png

После загрузки:

  • JSON описывает координаты иконок
  • PNG хранится как текстура в WebGL

Кэширование на GPU

В отличие от тайлов, спрайты часто хранятся:

  • в GPU памяти как texture atlas
  • с минимальным участием CPU после загрузки

Это снижает количество повторных операций декодирования изображений.


Внутренний ресурсный кэш Mapbox GL JS

Помимо браузерного кэша, библиотека поддерживает собственный слой кэширования ресурсов:

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

Этот слой управляет:

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

Если один и тот же ресурс запрашивается одновременно из нескольких слоёв, Mapbox GL JS инициирует только один сетевой запрос.


Управление памятью и эвикция

Кэш Mapbox GL JS ограничен по памяти. При превышении лимитов применяется стратегия удаления:

  • сначала удаляются наименее используемые тайлы
  • затем устаревшие glyph ranges
  • затем текстуры, не привязанные к текущему viewport

Система учитывает:

  • zoom level
  • положение карты
  • частоту использования регионов

Это позволяет поддерживать баланс между производительностью и потреблением памяти.


Очистка кэша и обновление данных

Полная очистка кэша может быть необходима при:

  • обновлении тайлов на сервере
  • изменении стиля
  • отладке

На практике используются следующие стратегии:

Перезагрузка стиля

map.setStyle(map.getStyle());

Этот метод приводит к повторной инициализации источников и пересборке кэшей.

Удаление и пересоздание карты

map.remove();

Полностью освобождает память, включая GPU ресурсы.

Версионирование URL

Часто применяется более эффективный подход:

/tiles/{z}/{x}/{y}.pbf?v=2

Это позволяет обходить кэш без вмешательства в код клиента.


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

Проблема инвалидации является одной из ключевых в системах картографии.

Основные стратегии:

  • добавление версии в URL ресурсов
  • изменение style URL
  • использование уникальных hash-параметров
  • настройка CDN cache-busting

Mapbox GL JS не предоставляет универсального метода принудительной инвалидации всех уровней кэша, поэтому ответственность распределяется между сервером и клиентской конфигурацией.


Офлайн-кэширование и локальное хранение

Для офлайн-режима используются дополнительные механизмы:

  • IndexedDB для хранения тайлов
  • локальные tile store
  • специализированные offline plugins

Офлайн-стратегии включают:

  • предварительную загрузку регионов
  • ограничение zoom range
  • хранение style JSON локально

При офлайн-навигации Mapbox GL JS может работать полностью без сети, используя заранее сохранённые ресурсы.


Service Worker как слой кэширования

В современных архитектурах часто добавляется Service Worker, который:

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

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


Практические аспекты оптимизации кэша

Эффективная работа с кэшем в Mapbox GL JS обычно достигается через комбинацию:

  • стабильных URL ресурсов
  • ограниченного количества источников
  • переиспользования style объектов
  • минимизации динамического создания слоёв
  • контроля над zoom-dependent data

Особое внимание уделяется предотвращению «cache thrashing», когда слишком частые изменения стиля приводят к постоянной перезагрузке ресурсов.


Поведение кэша при смене стиля

При смене стиля происходит:

  • проверка совместимых sources
  • очистка неподходящих tile caches
  • повторная загрузка glyph ranges при необходимости
  • обновление sprite textures

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


Особенности многокартовых приложений

При использовании нескольких экземпляров карты:

  • браузерный кэш общий
  • HTTP кэш общий
  • WebGL текстуры раздельные
  • Mapbox GL JS resource cache частично изолирован

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


Кэширование и производительность рендеринга

Эффективность кэша напрямую влияет на:

  • FPS при панорамировании
  • скорость zoom transitions
  • время initial load
  • задержки при смене стиля

Оптимальный кэш уменьшает количество операций:

  • декодирования PBF
  • загрузки изображений
  • пересборки vertex buffers
  • обновления WebGL state