Massive Google Maps. 5000 мест, 5 МБ. Как сделать это быстрее?
-
27-09-2019 - |
Вопрос
Я пытаюсь загрузить Google Maps V3, которые показывают 5000 маркеров кликабели. Мои JS содержит 10 строк на место:
var myLatlng_4821 = new google.maps.LatLng(43.0754329,-71.4699752);
var contentString_4821 = "<b>Place 1</b>";
var infowindow_4821 = new google.maps.InfoWindow({content: contentString_4821});
var marker_4821 = new google.maps.Marker({
position: myLatlng_4821,
map: map,
icon: image
});
google.maps.event.addListener(marker_4821, 'click', function() {
infowindow_4821.open(map,marker_4821);
});
Так что это дает мне 50 000 строк JS (5 МБ). Я хотел бы, чтобы кэшировать его, но Heroku не позволяет странице занимать более 30-х годов, чтобы я даже не могу получить его один раз.
Вы бы хотели загрузить эту страницу быстрее? Мне удалось только сделать это локально (занимает 45 ~). Мне больше нечего загружать. Я использую ROR.
Большое спасибо!
Решение (это довольно круто).
var myLatlng = [];
var infowindow = [];
var marker = [];
function MakeInfoWindowEvent(map, infowindow, marker) {
return function() {
infowindow.open(map, marker);
};
}
for (var i=0;i < places.length;i++)
{
myLatlng[i] = new google.maps.LatLng(places[i][0],places[i][1]);
infowindow[i] = new google.maps.InfoWindow({
content: places[i][2]
});
marker[i] = new google.maps.Marker({
position: myLatlng[i],
map: map
});
google.maps.event.addListener(marker[i], 'click', MakeInfoWindowEvent(map, infowindow[i], marker[i]))
}
}
Решение
Если я вас правильно понимаю, у вас есть пример код повторяется 5000 раз, с «4821», LAT & LNG и String Content отличается для каждого из 5000 маркеров?
Если это так, то вам нужно изменить свой подход, чтобы его данные были «повторенными», а не код ...
var markers = [
[43.0754329,-71.4699752,"Info for first marker"],
[45.0473490,-56.47688356,"Info for second marker"],
.
.
.
[20.1234384,12.23462566,"Info for last marker"]
];
for(var i=0; i < markers.length; i++){
var latLng = new google.maps.LatLng(markers[i][0], markers[i][1]);
var contentString = markers[i][2];
var infowindow = new google.maps.InfoWindow({content: contentString});
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: image
});
google.maps.event.addListener(marker, 'click', function()
{
infowindow.open(map,marker);
});
}
Это уменьшит размер вашей страницы значительной суммой и, вероятно, будет решить проблему кэширования.
Однако слово предупреждения - вышеуказанный код просто иллюстрирует, как удалить повторный код и заменить его на поиск данных, но могут возникнуть проблемы с созданием так много экземпляров InfoWindow сразу (вы, вероятно, лучше, создавая inwoWindow внутри слушателя , Кроме того, я не совсем уверен в видимости переменных в закрытиях, поэтому вы можете в конечном итоге с 5000 маркерами, имеющими атрибуты последнего элемента в списке (могут потребоваться небольшие изменения)
Другие советы
Поскольку вся необходимая информация для одного маркера, это:
[lat,lng,contentString]
... Вы можете хранить эти данные в массиве и затереть массив. В зависимости от ContentString вам теперь нужно что-то с 150 кБ, что не должно быть большой проблемой.
Если данные, связанные с отметками, не изменяются, вы можете использовать внешний JS-файл, поэтому браузер может использовать их из кэша в будущих посещениях.
Я не уверен, что накладные расходы на конструкторов для Google InfoWindow
и Marker
Есть, я могу представить, что они здоровенные, но я могу сказать вам, наверняка, добавив новую функцию, используя переменные замыкания, вы предотвращаете утилизацию каждого объекта в процедуре.
Это может объяснить большую часть вашей проблемы и является классическим сценарием для утечки памяти. Увидеть принятый ответ от это сообщение.
Я бы согласился на то, что вам будет лучше хранить то, что вам нужно в массиве, и только при необходимости в вашем обработчике клика.