Skip to content

Instantly share code, notes, and snippets.

@rdmurphy
Last active December 15, 2015 07:29
Show Gist options
  • Save rdmurphy/5223288 to your computer and use it in GitHub Desktop.
Save rdmurphy/5223288 to your computer and use it in GitHub Desktop.
"Hacking the URL" with Leaflet.js
<!DOCTYPE html>
<html>
<head>
<title>China Population</title>
<script src="http://cdn.leafletjs.com/leaflet-0.5/leaflet.js"></script>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
<style>
body {
margin:0;
padding:0;
font-family: helvetica
}
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
var map = L.map('map');
map.setView([33.338, 107.079], 5);
map.addLayer(L.tileLayer('http://{s}.tiles.mapbox.com/v3/bobbysud.map-9r8vorla,bobbysud.map-rekkc1s3/{z}/{x}/{y}.png'));
</script>
</body>
</html>

Hack the URL, Leaflet Style

As explained in a recent Mapbox blog post, it's possible to request a single tile image for multiple layers from the Mapbox service. If you use Mapbox.js, the library is smart enough to handle this for you. It's magical.

If you use Leaflet (like I do), you don't get that magic. Because Leaflet intends to agnostic to whatever tiles you throw at it, there's nothing there to "know" how to take advantage of what Mapbox offers.

But That's Okay!

After some poking around in the web console with the example, I noticed that the real Mapbox.js magic happens in the tile request, using the format detailed in the Hack the URL section.

How can Leaflet take advantage of this? It's easy.

Instead of doing this:

map.addLayer(L.tileLayer('http://{s}.tiles.mapbox.com/v3/bobbysud.map-9r8vorla/{z}/{x}/{y}.png'));
map.addLayer(L.tileLayer('http://{s}.tiles.mapbox.com/v3/bobbysud.map-rekkc1s3/{z}/{x}/{y}.png'));

Do this instead:

  map.addLayer(L.tileLayer('http://{s}.tiles.mapbox.com/v3/bobbysud.map-9r8vorla,bobbysud.map-rekkc1s3/{z}/{x}/{y}.png'));

And poof! You get combined tiles from the Mapbox server. In my tests (using these same layers; only these two lines were changed), it brought the number of onload requests (no scrolling or zooming tile loading included) to the browser down from 75 to 45, and the size of the transfer down from 672 KB to 588 KB. Nothing too crazy (about -12%), but hey, I'll take it!

All numbers are from cold loads in a Chrome incognito window.

(For comparison: Mapbox.js still outperformed both methods on transfer size, at 499 KB. It also made twice as many requests, at 101. I make no claims of expertise here, but I think the extra "requests" come from a bunch of these data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 being generated, one for each tile.)

@tswicegood
Copy link

12% reduction is huge. Lots of optimizations are considered successful at < 2%. Nice work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment