В MapLibre GL JS фильтры слоёв представляют собой механизм условного отбора геометрии из источника данных перед её отображением. Каждый фильтр — это выражение, которое вычисляется для каждой фичи в слое и определяет, будет ли она включена в рендеринг. На уровне архитектуры это операция, тесно связанная с фазой подготовки данных к отрисовке в WebGL-пайплайне.
Ключевой фактор производительности заключается в том, что фильтрация выполняется не один раз, а многократно: при каждом изменении состояния карты, включая зум, панорамирование, изменение стиля или данных источника. Поэтому даже небольшое усложнение фильтра может масштабироваться до значительных затрат при большом количестве объектов.
Фильтр слоя интерпретируется как дерево выражений. Каждый узел дерева — это оператор (логический, сравнения, проверки наличия свойств), а листья — значения свойств фичи или константы.
Основной принцип выполнения:
При большом количестве фичей (десятки и сотни тысяч) стоимость вычисления становится линейной относительно числа объектов и сложности выражения.
Наиболее дешёвыми являются операции прямого сравнения:
==)!=)>, <,
>=, <=)has)Такие операции обычно компилируются в простые инструкции и хорошо оптимизируются движком.
Фильтры с all, any, none
создают дополнительную ветвистость вычисления:
all может завершаться досрочно при первом falseany — при первом truenone — инверсия anyОднако при глубокой вложенности возникает рост количества операций и ухудшение предсказуемости исполнения на уровне JS-движка.
Наиболее дорогими являются:
concat, downcase,
upcase)Регулярные выражения особенно критичны, так как их стоимость растёт нелинейно при увеличении длины строки и количества проверяемых фич.
Любое изменение состояния карты (pan, zoom, rotate) может инициировать повторную оценку фильтров. При этом:
На больших наборах данных это становится доминирующим фактором CPU-нагрузки.
Векторные тайлы уменьшают количество фичей в конкретном слое, но вводят другую проблему: фильтры могут применяться на каждом тайле независимо, что приводит к повторной работе для соседних тайлов с перекрывающимися данными.
GeoJSON-источники, напротив, требуют полной обработки всего набора данных при каждом обновлении.
Эффективная оптимизация начинается с сокращения числа фичей до применения фильтра:
Чем меньше входной набор, тем ниже стоимость вычисления фильтра.
Фильтры, зависящие от масштаба, часто заменяются комбинацией:
minzoommaxzoomЭто позволяет исключить целые классы фичей на уровне слоя до начала вычисления выражений.
Такой подход особенно эффективен при визуализации плотных наборов точек.
Операции преобразования строк внутри фильтра существенно увеличивают стоимость:
downcase и upcase требуют обработки каждой
строкиconcat создаёт новые временные значенияБолее эффективный подход — хранение уже нормализованных значений в свойствах данных.
Глубокие вложенные конструкции увеличивают:
Плоские фильтры с минимальной вложенностью работают заметно быстрее.
Фильтрация в стиле часто заменяет собой индексирование, которое отсутствует в рантайме.
Более производительный подход:
Например, вместо фильтра по типу:
Это устраняет необходимость проверки == "road" для
каждой фичи.
Изменение фильтра во время выполнения приводит к:
Частые обновления фильтров (например, при интерактивных UI-элементах) создают постоянную нагрузку на main thread.
Оптимизация достигается через:
Хотя сами фильтры выполняются на CPU, их результат влияет на GPU следующим образом:
Слишком сложные фильтры могут привести к фрагментации батчей, снижая эффективность отрисовки WebGL.
Фильтры вида:
обладают минимальной стоимостью и хорошо масштабируются.
Фильтр не должен выступать как вычислительный слой бизнес-логики. Любые трансформации данных лучше выполнять:
Чем меньше условных ветвлений внутри одного слоя, тем стабильнее производительность. Разделение слоёв позволяет:
При работе с сотнями тысяч и миллионами объектов ключевым фактором становится не только сложность фильтра, но и:
В таких сценариях даже линейная сложность фильтрации становится критической, и архитектурные решения начинают играть большую роль, чем микрооптимизации выражений.