MapLibre GL JS использует WebGL-пайплайн, где каждый кадр формируется через последовательность этапов: загрузка источников данных, подготовка тайлов, построение буферов геометрии, применение стилей и финальный рендеринг на GPU. Производительность в такой архитектуре определяется не одной точкой, а совокупностью узких мест: сеть, память, CPU (worker-потоки) и GPU (отрисовка слоёв).
Оптимизация рендеринга сводится к контролю количества обрабатываемых данных, снижению стоимости пересчёта стилей и минимизации количества draw calls.
Наиболее частая причина падения FPS — перегруженные GeoJSON-источники. MapLibre обрабатывает их в worker-потоках, но дальнейший рендер всё равно зависит от итогового количества вершин.
Ключевые подходы:
maxzoom для тяжелых слоёвmap.addSource('cities', {
type: 'geojson',
data: simplifiedGeojson,
maxzoom: 10
});
Векторные тайлы позволяют переносить тяжёлую обработку на этап генерации тайлов, а клиенту отдавать уже сегментированные данные.
Преимущества:
Важно контролировать:
Для больших наборов точек кластеризация снижает количество renderable-объектов.
map.addSource('points', {
type: 'geojson',
data: points,
cluster: true,
clusterMaxZoom: 14,
clusterRadius: 50
});
Оптимизационный эффект достигается за счёт уменьшения количества символов и collision checks.
Каждый слой — это отдельный проход рендеринга. Даже при одинаковом источнике несколько слоёв увеличивают количество draw calls.
Практика:
case
expressionsФильтры выполняются на CPU и могут становиться узким местом при сложных выражениях.
Рекомендации:
casefilter: ['all',
['>=', ['get', 'value'], 10],
['<', ['get', 'value'], 100]
]
Symbol layers используют collision detection, который является дорогой операцией.
Оптимизация:
symbol-sort-keytext-optionallayout: {
'symbol-sort-key': ['get', 'priority']
}
Raster sources дешевле в GPU-обработке, но зависят от сети и памяти.
Оптимизация:
tileSize: 256 вместо 512 при
необходимостиmap.addSource('tiles', {
type: 'raster',
tiles: ['https://example.com/tiles/{z}/{x}/{y}.png'],
tileSize: 256
});
Векторные слои требуют больше CPU, но дают гибкость. Основные оптимизации:
paintКаждое динамическое выражение в paint пересчитывается
при каждом кадре.
Проблемные конструкции:
match с большим количеством условийzoom + feature-stateРекомендация — выносить вычисления в подготовку данных.
Blending операций много на GPU приводит к падению производительности:
Практика:
Частые вызовы setData создают перерасчёт геометрии и
пересборку буферов.
let timeout;
function updateData(data) {
clearTimeout(timeout);
timeout = setTimeout(() => {
source.setData(data);
}, 100);
}
Любое изменение:
может инициировать полный или частичный repaint.
Оптимизация:
batch operationssetLayoutProperty точечноЗагрузка glyph atlas может стать узким местом.
Рекомендации:
text-fonttext-size диапазонаИконки хранятся в sprite atlas, и его размер влияет на:
Практика:
MapLibre активно использует HTTP cache для тайлов.
Настройки сервера:
Cache-Control: max-ageПозволяет уменьшать задержки и оптимизировать запросы:
transformRequest: (url) => {
return {
url,
headers: {
'x-map-client': 'web'
}
};
}
Один из самых эффективных способов снизить нагрузку.
map.addLayer({
id: 'buildings',
type: 'fill',
source: 'composite',
'source-layer': 'building',
minzoom: 14,
maxzoom: 18
});
Это уменьшает количество обрабатываемых объектов на ранних zoom-уровнях.
Разделение геометрии по уровням детализации:
Такой подход снижает GPU-fill rate и CPU geometry processing.
Feature-state позволяет динамически менять стиль объектов без пересборки источника, но при массовом использовании создаёт нагрузку на память.
Оптимизация:
Основные показатели:
WebGL profiling позволяет выявить:
Типичный цикл:
Overdraw возникает, когда один пиксель перерисовывается несколько раз разными слоями.
Способы снижения:
Частые события mousemove или render могут
приводить к перегрузке логики.
Подходы:
queryRenderedFeatures только при
необходимостиВысокая производительность достигается только при согласованной оптимизации:
Каждый слой карты становится не просто визуальным элементом, а узлом вычислительной нагрузки, где любое усложнение напрямую отражается на стоимости кадра.