Как работает Google Maps на стороне frontend
Что проверяют
Понимаете ли вы, как браузер показывает огромную карту, не загружая мир целиком: тайлы, проекция, WebGL, подгрузка по видимой области. Второй слой вопроса практический: как подключить Maps JavaScript API, как вывести тысячи точек и не убить производительность.
Как отвечать
Устройство веб-карты:
- тайлы: мир в проекции Web Mercator режется на квадраты по уровням зума, на каждом следующем уровне их в четыре раза больше. Грузятся только тайлы видимой области с запасом по краям, браузер их кеширует;
- векторные тайлы и WebGL: современная карта получает не картинки, а геометрию и подписи и рисует их на клиенте через WebGL. Отсюда плавный зум, наклон и поворот, а стиль меняется без перезагрузки;
- интерактив: жесты через pointer events, инерция при панорамировании, во время анимации растягиваются тайлы соседнего зума, пока не пришли нужные;
- подписи: расстановка с проверкой пересечений, чтобы тексты не наезжали друг на друга.
Как работает API на практике. Актуальный способ загрузки это динамический импорт библиотек через google.maps.importLibrary("maps") или пакет @googlemaps/js-api-loader, ключ передаётся при подключении. Карта создаётся через new Map(element, { center, zoom, mapId }). Для маркеров сейчас рекомендуют AdvancedMarkerElement: старый google.maps.Marker объявлен устаревшим, а продвинутые маркеры и векторная карта требуют mapId. Свои данные рисуют полилиниями, полигонами или слоем Data из GeoJSON.
Про производительность: тысячи DOM-маркеров тормозят, их кластеризуют (@googlemaps/markerclusterer) или рисуют одним слоем через WebGL, например deck.gl. Данные с сервера запрашивают по текущим границам после события idle, а не на каждое bounds_changed.
Где спотыкаются
Пересказывают старый пример с callback=initMap и google.maps.Marker, не зная, что это устаревший путь.
Считают ключ API секретом или, наоборот, оставляют его без ограничений. Ключ всё равно виден в браузере, поэтому его ограничивают по HTTP referrer и по списку разрешённых API.
В React создают карту заново при каждом рендере. Экземпляр создаётся один раз в эффекте с ref на контейнер, а дальше меняется через методы API.