Question

I'm trying to load a Google Maps v3 that shows 5000 markers clickable. My JS contains 10 lines per place:

              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);
                                      });

So it gives me a 50 000 lines js (5MB). I would love to cache it but heroku doesn't allow a page to take more than 30s to load so I can't even cache it once.

Would you have any tricks to load this page faster? I only managed to do it locally (takes 45s~). I have nothing else to load. I use RoR.

Thanks a lot!

SOLUTION (it's pretty cool).

 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]))

                  }
         }
Was it helpful?

Solution

If I understand you correctly, you have the example code repeated 5000 times, with '4821', the lat&lng and the content string differing for each of the 5000 markers?

If so, then you need to change your approach so that its the data that is 'repeated' and not the code...

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);
    });
}

This would reduce the size of your page by a significant amount, and will probably solve the caching issue.

A word of warning though - the above code merely illustrates how to remove the repeated code and replace it with data lookup, but there may be issues with creating so many InfoWindow instances at once (You would probably be better off creating the InfoWindow inside the listener. Also, I'm not completely sure about the visiblity of variables in the closures, so you may end up with 5000 markers having the attributes of the last item in the list (slight changes may be required)

OTHER TIPS

As all information you need for a single marker is this:

[lat,lng,contentString]

...you could store this data in an array and loop the array. Depending on the contentString you should now need something from 150KB upwards, what shouldn't be a big problem.

If the data related to the markes doesn't change you can use an external js-file, so the browser can use them from it's cache on future visits.

I'm not sure what the overhead on the constructors for the Google InfoWindow and Marker are, I can imagine they're hefty, but I can tell you for sure that by adding a new function using the closure variables, you're preventing the disposal of EVERY object in the routine.

This may account for the majority of your problem and is a classic scenario for a memory leak. See the accepted answer from this post.

I would agree that you'd be better off storing what you need in an array and only instantiating when necessary in your click handler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top