Lazy Loading Google Maps and Microsoft Virtual Earth

I’m not sure how the phrase goes exactly, but it includes the words “necessity”, “invention”, and “mother”.

To say that my employer’s Internet connectivity can be spotty is a bit of an understatement. Besides frequent slowness and increasingly frequent “goneness”, this past week we had something new. The “qbot” trojan is eating its way through the county, and despite the 5-star dining experience Microsoft offers malware of all kinds, it seems to offer no love in return - the county’s connection to anything Redmond slowed to a crawl, perhaps because we were pinging the bejesus out of them. Which means a site I had that loaded the Virtual Earth library was really, really hung. Anybody outside the county’s network was aces, but anybody inside our network was doing a lot of thumb twiddling. And although outside users outnumber inside users by at least 100x1, the inside users know where my office is.

I was being relatively good about lazy loading the Google Maps and Virtual Earth libraries - I was loading those after page load, so users wouldn’t have to sit around waiting just to see the page. This is really for popup widgets, so they aren’t needed on page load. But with the latest problems, I needed to get even lazier. If there was ever a programmer born for this task, it is I.

Lazy loading Google Maps is fairly trivial. Google has AJAX API’s ready for the taking. In your page load, just reference the Google Javascript API, and include your Google Maps key.

<script src="http://www.google.com/jsapi?key=your_key_here"></script>

Now, on a page click or whatever is going to trigger the map, just:

google.load("maps", "2", {"callback": mapLoad });

Where mapLoad is your function initializing the map and whatnot. Google will load the map library for you and run the map code after its loaded.

Virtual Earth is a different animal. jQuery has a built-in function to handle lazy loading Javascript, like so:

$.getScript("http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2", mapLoad);

Epic fail here. The problem is that VE will essentially load a file that tries to load more files, and you’re skipping off to the mapLoad event when the first one is loaded. Your browser will tell you it has never heard of this VEmap thing, and that you should go jump in a creek.

To pull this off with VE, I had to try to figure out if it was really done loading. After scrounging around forums and trying three other things, here’s what I ended up with:

$.getScript("http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2",
function() {
var myInterval = setInterval( function() {if (( eval("typeof VEMap") != "undefined")
&& (document.getElementById("vemap").attachEvent != undefined))
{clearInterval(myInterval);  mapLoad  }},  2000);
});

The oft-underused setInterval command is a lot like a setTimeout, but with one difference. With the setInterval, it trys to execute the code at every interval, not just once. Basically what I’m telling the browser to do is to check to see if VEMap and attachEvent are there yet, which would indicate VE is loaded and ready. I perform the check for 2 secounds after the inital VE JS file is loaded. When both are present, I clear the interval, killing the loop, and run my map code.

If you aren’t using the map libraries at page load, it’s a good idea to lazy load them, even if your Internet connection is solid as a rock. It saves the user time, and there’s always the chance they’ll never go the the magical link that requires a map to load.