
Быстрый и динамичный рендеринг кластеров Leaflet — давайте сравним 3 метода
Карты во фронтенд-разработке
В какой-то момент карьеры каждого фронтенд-разработчика наступит время, когда перед ним встанет задача реализовать карту. Есть много применений карт в приложениях. Сегодня я сосредоточусь на картах, содержащих большое количество точек с определенными координатами. Это могут быть, например, пункты выдачи, рестораны, магазины и т.д.
Leaflet – это стандартное решение, которое разработчики часто используют из-за его открытого исходного кода. Сегодня мы поговорим об этом.
Представим теперь, что наша задача — добавить определенные точки на карту, но мы добавляем их не один раз после запуска карты, а отправляем запрос на точки каждую время перемещения по карте (перемещение или изменение масштаба). Звучит знакомо?
Кластеры листовок в действии
Если это так, вы, вероятно, встречали рекомендованный плагин Leaflet, Leaflet.markercluster. В документации мы можем найти примеры, где реализовано 10 000 или даже 50 000 точек! Кроме того, благодаря chunkedLoading мы можем отображать многие точки на карте в относительно удобном для пользователя виде. Ниже вы найдете пример кластеров Leaflet с официальной страницы проекта на Github:
https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.50000.html
Отлично, плагин может справиться со значительными проблемами, поэтому он будет динамически добавлять баллы, верно? Не так быстро! Да, Leaflet.markercluster работает неплохо, и это тоже решение, которое я представил в своем недавнем проекте, но ключом к успеху в данном случае являются знания.
А теперь представьте такую ситуацию: в начале вы добавляете на карту 350 точек. Затем пользователь перемещает карту — у нас есть новая область карты, поэтому мы отправляем еще один запрос на новые точки и снова генерируем 350 точек на карте. Звучит просто, но это не так. Потому как вы узнаете — эта операция занимает много времени. Не десятки миллисекунд и даже не несколько сотен. Это занимает 2–3 секунды, а иногда и больше!
Я даже не хочу думать о том, каких цифр мы можем добиться при медленном интернет-соединении. Это происходит каждый раз, когда вы перемещаете карту или меняете масштаб! Чем больше логики связано с картой (добавлено, например, поисковая система, пользовательские значки маркеров и т. д.), тем более удручающими могут быть эти результаты.
Вы, наверное, думаете: зачем каждый раз прибавлять по 350 точек, если мы можем запомнить те, что уже есть, и добавить только те, которых еще не было на карте. Кроме того, вы можете удалить те маркеры, которые не находятся в видимой области карты, верно? Звучит замечательно :) Однако такая операция в случае с Leaflet.markercluster может оказаться самоубийством!
Решение проблем с производительностью Leaflet.markercluster
Наша команда перерыла весь интернет в поисках ответов, пытаясь справиться с оптимизацией нашей карты. У нас было много нестандартных решений (например, поисковая система и множество нестандартной логики), но, как оказалось, они не были источником проблемы. Наконец, однажды я наткнулся на увлекательную заметку Данзела, который подробно объяснил ситуацию.
Оригинал поста вы можете найти здесь:
Это было похоже на поиск Святого Грааля!
Как вы, наверное, заметили, когда вы динамически меняете точки на карте, самым быстрым решением будет… удалить все точки и применить их заново! Даже те, что уже есть на карте! Нет выбора. Очистить и вставить. Почему?
Сравнение методов кластеров листовок
Все благодаря эффективности конкретных методов Leaflet.markercluster. Подробное их сравнение можно найти ниже. Для тестов я установил 10000 точек и поставил их менять после перемещения карты, а песочницы сделал для трех разных случаев. Я не стал добавлять дополнительную логику для удаления кластеров за границы. В этих примерах я придерживаюсь простоты и сравниваю только методы добавления/удаления.
Вы можете увидеть результаты в мс в консоли:
removeLayer в сочетании с addLayer
РЕЗУЛЬТАТЫ:

removeLayers в сочетании с addLayer
РЕЗУЛЬТАТЫ:

clearLayers в сочетании с addLayers
РЕЗУЛЬТАТЫ:

Как вы могли заметить, сочетание clearLayers с addLayers — два самых быстрых метода, и я настоятельно рекомендую использовать их в своем проекте!
Результаты впечатляют, и, как видите, самые очевидные решения не всегда самые лучшие. Изменив метод добавления и удаления маркеров на карте, мы улучшили ее производительность более чем в 10 раз! Помните об этих оценках, если будете внедрять Leaflet с Leaflet.markercluster. Это может сэкономить вам много часов поиска решения.