Google I/O 2009 - Performance Tips for Geo API Mashups

Uploaded by GoogleDevelopers on 01.06.2009

Pamela Fox: Just curious, how many of you
were in the earlier talk?
The grab bag kind of--sweet.
All right, cool, you guys are like--
we just kind of have a club of people that like maps and stuff.
All right, so now we're gonna get into
a bit more of an advanced topic,
and talking specifically about-- we're talking about
the 2D maps APIs here and performance tips.
As we know, performance is really important
to making good websites.
And there's a couple of us that are gonna be talking today,
so there's me, and most of you guys know me now,
and we have Sasha from Redfin,
and we have Marcelo from Google,
from the Sydney office.
Do I need this part? Right, right.
So, uh, so the reason we're talking about this:
because one of the things that's really important
to us at Google is latency.
And I'm sure you heard spiels from Larry and Sergei before,
but basically, we're not gonna launch something
unless it's fast enough, right?
If the web page is fast, then the user is happier using it,
and they can get what they want to faster.
And when you think about it from a Google perspective,
that means more time for them to click on ads.
So, uh, more money, right?
So that's what, you know, kinda what it boils down to,
but, basically, latency is really important,
and we want to make sure that you guys
can use our stuff, and create fast experiences
for your users.
It's really when I-- like, I monitor Twitter
for Google maps API,
and whenever I see somebody say,
"Oh, the Google maps API is taking too long,"
then I get really sad and cry.
So this is really just a session
so that I don't cry as much.
Still a bit, though.
All right, so, um,
one of the initial things that makes an API slow
is actually loading the API
because JavaScript loads into the browser.
And to talk about that we have Marcelo.
Marcelo: Hi, guys, my name is Marcelo.
I work on the Maps API team back in Sydney,
and I'm here to talk about latency issues
when loading the JavaScript API.
So, as you know, the browser has--
there are a lot of resources
before I can actually display interactable, uh, map
to the user.
Mainly image files and JavaScript files.
These resources are loaded in a very well-defined sequence.
And let's call, for now, the sequence
the Loading Sequence.
So I think it's interesting for us to take a closer look
at how time is spent during this loading sequence.
that can have some insight about where the latency hotspots are.
So the first thing that comes down the pipe
is the bootstrap.
The bootstrap is a small JavaScript file
that the browser downloads
when it encounters the maps API--
the script tag at the top of the page.
The bootstrap comes down, gets executed
at around 2.5 seconds,
and it will then download main.js.
Main.js is the bulk of the JavaScript API.
It get downloaded and initialized
at around 3.1 seconds.
It's only after the page has set a center on the map,
that the map will actually start downloading tiles.
On a typical map,
we know that setCenter's called at around 3.8 seconds,
and the tiles will finish downloading
at around 4.6 seconds.
So, there you have it-- around five seconds
before the user can actually start interacting with the map.
It's not too bad, but it's not great.
But if you look on the iPhone and Adroid platform,
the numbers look pretty scary.
Main.js, for instance, takes nine seconds
to download on the iPhone.
That's in comparison to 3.1 seconds
on the desktop platform.
And the tiles would only be visible
after 18 seconds.
That's 13 seconds later than you would on a desktop platform.
So we think that's pretty unacceptable.
So there's a couple reasons for that.
One of the reasons-- just too many files
for the browser to download.
First, it comes the boostrap and then main.js,
and they have to be, because of their nature,
they have to be downloaded in sequence.
We can not paralyze those.
And only after the map know where the center is,
they can start downloading the tiles.
A typical map will require from 9, 12,
all the way up to 25, 36 tiles,
depending on the size of the map.
And, as you guys may know,
each file request carries a lot of overhead,
especially over a high-latency network,
like 3-D, for instance.
So that's where the 19 seconds is coming from.
So what we suggest to get around this
is to use the Static Map API.
So with the Static Map API,
you can fetch a static view of the map,
put that into-- into the maptive,
and you're able to show, you know,
a useful map to your user much earlier.
Of course, it won't be interactable,
but the user will get to see something
while he's waiting for the
[indistinct] API to be downloaded in the background.
If you do that,
you will be replacing, in this specific example,
a 200KB download, split over 10, 20 small files,
with a single download of around 80KB in size.
So it's, you know--
you're much more likely to give a map
to a user earlier.
I have a little demo here
that implements this.
Let me just show you guys.
Let me just...
May I?
I clear your cache. Pamela: Uh, yeah.
Marcelo: Okay.
So let's just see here the on-demand demo.
Pamela: Thank you to Barry in the audience
for this demo.
Marcelo: Uh, okay.
Pamela: What are you looking for?
Marcelo: Uh, sorry, oh.
Pamela: Oh, yeah. Marcelo: Okay, there you go.
So you can see there, it's downloading
the page and just a static map,
and show that shortly to the user,
and wait until the user clicks--
the user click on the map.
That's when--
the JavaScript API is actually downloaded.
And this other demo here
does sort of the same,
but it doesn't wait for the user
to track to the map.
So it doesn't transition really quickly.
Of course, if your user
is in a slow connection,
he--there will be a delay
where he wouldn't be able to interact with the map.
but that's better than get a blank div.
the other big reason why it can be so slow
to load a map on a mobile device
is just the sheer size of the API.
If you look at this, this is the list of classes
that the public interface implements.
And that all adds up to about 220KB of JavaScript.
The problem with this
is that we just recently found out
that the iPhone takes around 20 milliseconds
to parse each KB of JavaScript.
So if you multiply that, what you get is 4.4 seconds.
That's the amount of time that the browser will wait
for the Jesup engine to digest all this JavaScript code.
And during this time, the browser
is completely unresponsive.
So again, it's a really unacceptable user experience
in our opinion.
So to try to alleviate this problem,
what we are doing is offloading some of the code
that currently sits in main.js
into js modules.
These modules can be downloaded dynamically
after the tiles have arrived,
so they don't hog the CPU
during the start-up sequence.
So far, we've been able to modularize around 20%
of main.js,
but unfortunately, there's a major obstacle
to this work.
which is the fact that the API was designed a few years ago
around a synchronous programming model
that doesn't play really well with dynamic modules.
And the fact that we cannot, for obvious reasons,
change the public API,
makes this a major, uh, show-stopper for us,
as far as motorization goes.
So after a lot of discussion
back in Sydney,
the team decided to bite the bullet
and start working on the next generation
of the API, which we call Maps API v3.
The Maps API v3 is being released today.
There's a blog post up.
The [indistinct] is also up.
You guys can check it out-- see what you think
about the API,
give us feedback, maybe try the demos,
even try to come up your own mashups.
And I'll just finish my presentation here
with, you know, a few bullet points
of why we think that v3 is so special.
The first thing is, uh,
v3 is built from the ground up with latency in mind.
So we are going for a very aggressive
JavaScript modularization,
and that fact that we don't have a well-established API,
a legacy API, if you like, to hold us back
is a real blessing.
We also baked some latency-specific features
into the API.
So, for instance, the Static Map optimization
I just told you guys about
is actually built into the API,
so it's really easy for developers
to deploy that into their websites.
And, last but not least, we really, really committed to
the iPhone and Android platforms,
and we hope we can provide
the best user experience possible.
And Susannah, who is with us today,
will be giving a presentation tomorrow,
where she'll go into much more detail
about v3 and how to use it.
So I really recommend you guys attend.
Pamela: All right, thank you, Marcelo.
Pamela: So now with that nifty new android you got,
you can make maps that work really well on it.
You see.
So, I know we didn't give you an android,
but we gave you a tool to harness on the android,
which is just as good, really.
So that is our new API,
and that's going to solve some of the latency issues
with loading in JavaScript in lots of resources.
But there are still other performance issues,
both for that API and for the current API generally.
So one of these is the issue
of trying to display many markers on the map.
Now, this is a very common question we get in the group,
is, "Hey, I tried to put ten thousand markers on the map,
and then my browser got really slow."
what can I tell you?
You tried to put 10,000 markers on the map.
So the thing is, that remember that
the map's API JavaScript
was originally created from the Google Maps JavaScript,
which meant that everything-- all the classes we had
were classes we originally designed
for the use case we had in mind.
And the use case on Google Maps
is you do a search,
and you get back ten labeled markers,
and that's it.
Google Maps almost never--well,
sometimes they do now,
but generally never shows more than ten markers at a time.
So to design the GMarker class,
with this in mind.
They wanted a lot of features.
They wanted printability; they wanted dragability.
They wanted foregrounds, shadows.
They wanted hotspots that would work
in every single browser,
including IE6.
All this, which means that GMarker
is a really full-featured class,
which means that it actually contains
a lot of DOM nodes in order to create it,
and make it work correctly.
So that means, if you try and put 10,000 markers on a map,
what you're actually putting on a map
is something like 50,000 DOM nodes.
And the thing is,
if you try and put 50,000 DOM nodes in the browser,
the browser gets really, really sad.
So we don't want to make it sad so it cries.
So what you can do is that,
in the API we have a GOverlay interface,
and you can extend this overface
to create your own custom overlay.
So I'll just show you an example of one that I made,
so you--all you have to do is make a marker
that just doesn't have as many features
as our marker has,
and is optimized for what you want
your markers to accomplish, right?
If you want your markers to have thousands of them,
and, uh, be clickable,
you can do that with not much lines of code at all.
So we can see a demonstration here.
I'll do GMarker.
It's gonna be a bit slow.
And we're adding a thousand--
oh, that's gonna be really bad.
You can see the shadows turned up first,
and then we have the markers.
So that kind of took a while,
and then--well, panning isn't really, like, that fun.
So now, I'll do...
a thousand Marker Light.
So you see that was a lot faster,
and the panning is smoother too.
And even then, this isn't an extreme optimization.
All I've done here is create an overlay
that has one div with an image DIV inside,
so I've reduced from 5 DOM nodes to 2 DOM nodes.
So this is a performance enhancement already,
but you can go even more extreme than that,
and I'm gonna have Sasha from Redfin
talk about his extreme solution.
Sasha: I don't know how extreme it is,
but, uh, so as Pamela said, my name is Sasha.
I work for Redfin.
We're an online web real-estate company.
And, from the beginning, we took the map
as the center of our user interface.
It's--you can do, sort of, polygon-based search,
you can search for neighborhoods,
and we show a lot of houses on the map by default.
We show up to 500 at a time,
and it's been a problem for us for a long time.
So, we actually-- we actually took Marker Light,
and we've added a bunch of stuff to it.
And I'm just gonna show you how it works on our site,
and then take you through
a very simplified version of the code
just to--so you get an idea of what the code looks like.
All right.
It's in Firefox, right?
So here we are at Redfin--
Let's give ourselves a little bit more space.
We've got some houses on the map;
we're looking at Potrero Hill.
Let's say, though-- we, you know,
we're interested in, what, in the bargains,
so let's look at, uh,
San Francisco, let's say, under 550K.
That's affordable, right?
All right, so it just added
477 things to the map right there.
And you see it happened pretty darn fast.
This is actually waiting for the network.
And...that's adding.
And so we're adding--
so you saw the demo that Pamela just did
of adding a thousand normal GMarkers.
Obviously, it happened a lot faster here.
So how do we do that?
So we did, basically, what Pamela just described:
subclass GOverlay.
We called it, actually-- We called it SuperMarker,
which, 'cause, I don't know,
'cause we wanted to do one better than
Marker Light, I guess. [laughs]
So what you do is you subclass GOverlay,
and this is just really simple beginning code
to say, "Okay, we've got a layer and a DOM node."
We're holding onto a DOM node.
The basic way this strategy works
is, as far as Google Maps is concerned,
SuperMarker is just one marker.
The thing--the GOverlay subclass is just one marker on the map,
but underneath it we're gonna draw stuff inside SuperMarker.
So we're gonna--we're basically gonna keep track of
all of the things we want to put on the map--
all the houses we want to put on the map
and tell SuperMarker about them sort of secretly.
So you have to implement a method called initialize,
which gives you the map,
uh, the G Map you're a part of.
And all it's doing right here
is just creating a DIV element
and adding it to a particular pane in the map.
So this is the DIV element, the DIV node--
it's gonna--the DOM node it's gonna hold on to
to do its own drawing.
Now you--you implement a draw method.
And there are a couple interesting things
to look at in this one, in this thing.
And most of the interesting performance things here
don't really have to do much with the map.
A lot of you probably know some of this,
but, as Pamela said,
adding 5,000 DOM nodes makes things very slow.
But it's also so--you wanna reduce the number of DOM nodes,
and we're only doing one DOM node per marker, here.
But other things that help are
that you don't do-- use the DOM APIs,
that you make a big string,
and slam it all in within your HTML--
makes it much faster to add things.
You'll also notice that,
instead of doing, you know, plus equals on the string,
it creates an array and joins the array at the bottom--
also much faster.
And the third thing to notice
is that it actually is creating--
we're--in this-- in our version
we only create one DOM node per marker,
and then we use what's called CSS Sprites
in order to put the image on it.
So rather than doing a DIV
with an image underneath it,
we use--we have one gigantic, uh, image
that has a bunch of different kinds of icons
because we have about,
I don't know, maybe a hundred different icons
depending on what kind of house it is,
what type of house,
whether it's a favorite of yours, et cetera.
We put them all together into one giant image
that's just one download to the browser,
and then we use CSS-- the CSS background image--
to select out little pieces of that image.
So it's just a DIV with a background.
The downside of this is... won't print.
As Pamela said, markers are very full-featured.
They have all these things.
They have shadows, they have printability.
You're not gonna get printing,
but it's gonna be a lot faster.
So that's the drawing right there.
And then finally,
once you've written this GOverlay,
all you need to do is just, basically, add it to the map,
and underneath the covers, you tell it,
"Hey, here are the ten things you need to draw."
And it makes the DOM nodes for you.
And that's it.
Pamela: So that was all using the JavaScript API,
but, actually, the Flash API,
though it does tend to be a lot faster at stuff,
can still run into the issue
of having too many things in the DOM.
So people in the Flash API community
have implemented really similar solutions
to SuperMarker.
I think they call it Super Overlay.
And where did you drag it to?
Too many tabs.
You guys are cheating.
You can see too much.
All right, I'll just open it.
So here's an example:
this is a map of victims of some dude named Madoff.
You guys probably know more than me.
This is a Flash map,
and you can see
it's got thousands of markers on here,
and as I mouse over the markers,
I still have interactivity,
and they even raise to the front here.
So that's the thing.
When you implement your own overlay,
you can implement stuff, like,
you know, changing the Z index.
It's really entirely up to you
what you want to implement there.
All right.
Still this hasn't really solved our problem,
if we want to put ten thousand markers.
This will work pretty good for five hundred markers,
for a thousand markers.
But ten thousand markers-- that's just too much.
Even just ten thousand DOM nodes...
that's still too many to put on the map.
So there's a couple different solutions here.
One of them is clustering,
which is becoming more common now.
Here's a classic example of clustering,
which is AuthorMapper.
You can see it here,
and they have stuff, like, individual markers
to signify, okay, there's only one author, here,
and then multiple markers to say,
all right, this is a cluster.
They also use the coloring
to indicate the size of the cluster.
So you see, okay, red means that there are more articles there,
and yellow means less.
And these are standard features of clustering sites.
Here's another example, which is [indistinct].
And, you see, they also use numbers
on the cluster markers,
and when you mouse over, you get a little thing
that says, "Oh, this is how many things are here."
And now you can zoom in,
and then the clusters would expand out
to either more clusters, or maybe some individual markers.
And you can see some of them here.
So this one is actually-- the way they implement this
is that--I think it's every night or every week or so--
they crunch through the data on their database.
They run it through a K-means Clustering Algorithm,
and then they save out the cluster information
to their database.
So it is a fair amount of effort
for them to actually implement this clustering algorithm.
So what--I'm really happy that now, actually--
a few month ago we announced MarkerCluster,
an addition in the Open Source library,
and what MarkerCluster is, is that it's actually
a JavaScript-only cluster
that will do all the clustering for you.
And all you have to do is pass in...
pass in the data that you want.
And it's a very naive cluster,
okay, it just does--
it, basically, uh, breaks it up into
a pixel grid,
and you can kind of specify the size that you want.
And then it will figure out the best clusters.
But they thing is, like, K--
you don't have to write a K-means Clustering Algorithm.
It'll do it purely in JavaScript,
so you don't have to store
a database of your marker clusters.
And it's pretty fast as well.
There's an example that does
a performance test as well.
So if you're looking
for a very fast clustering solution,
I highly recommend checking out MarkerCluster.
Since it is open source, you could tweak it yourself
to, uh, if you need to change the algorithm a bit.
So that's kind of standard clustering.
You could also do regional clustering.
So if it makes sense to cluster your data
by some political region like city, state, country,
continent, etcetera,
then you can divide all your data into those clusters,
and make cluster markers for each of those.
And you see, in this example,
when I mouse over one of the cluster markers,
I actually see the outlined polygon for that region.
So that's a nice hint to the user,
like, hey, these are actual regional clusters.
And they understand, like, oh, okay,
this represents California.
Because that's the thing with clusters--
is that you want to be clear
about what it's actually representing.
You can see that here.
And, actually,
travellr is a site that just launched recently,
which is kind of like Yahoo Answers for the map,
and probably has smarter users than Yahoo Answers does.
And you can see, it's nice.
They start off with continents.
And we can mouse over and see what they represent.
They haven't done border polygons yet,
but I've asked them to.
[laughs] Nicely.
What I like-- this is a pretty good
user experience here,
because I know exactly what these clusters represent,
and I can zoom in to see more information.
And they implement this on the server
using--I think it's a B plus tree
or something like that.
So those are different types of clustering you can do,
and it's kind of up to you, like,
how extreme you want to take it,
and how much you want to customize it.
There's an article here
that compares the various clustering arguns available.
That's a link to some sample K-means clustering code
if you want to write it yourself on a server.
And Maptimize is actually a, um,
basically, you give them their data,
uh, you give them your data,
and they'll go run it through
their own clustering algorithm on their server,
and then they'll just give you some JavaScript,
for you to include on your site,
and get the clusters to show up.
So they're kind of a hosted clustering solution.
And you have to pay.
A bit.
Not too much.
So there's clustering,
and clustering is what you use
when you want to make sure
that the user can eventually actually click on the marker.
Because with clustering, you can always zoom in far enough,
and actually have clickable markers.
But that's not always necessary.
Sometimes when you have ten thousand markers,
you don't really care about people clicking.
You just care about them visualizing the information
that you have.
So there's a couple ways of doing View-only visualizations.
So this is, um, FundRace from Huffington Post.
And this is really nice here.
What they've done is that
they geocoded the campaign contributions
from everyone in America,
and then plotted them on the map.
And then what they did was--
they actually created tiles,
and then they put them underneath
our hybrid upper layer.
And so these tiles--
it's basically like dot density mapping.
They've just done a pixel
for every contribution that they have.
And it's pretty cool because you can go and zoom in,
and then see, in your area,
exactly how red it is, and how blue it is,
and whether you should be hating on your neighbors,
and stuff like that.
And it's good because it doesn't--
you know, you can click on it, and you can zoom in,
and you can see-you can get the general idea
of how red or blue an area is,
but as a user I don't really expect
to be able to click on a pixel
and find out exactly who that pixel represents...right?
I can look and see some samples in the sidebar here,
and see who--what kind of people these people are.
But they don't have to worry about people mining down
to that-- individual pieces of data.
So this is something you could think about,
and this does involve actually rendering out
tiles on your server,
so they have some image manipulation,
where they're just writing pixels into the tiles,
and then putting them out.
Something similar you can do
is a HeatMap,
and there actually is a HeatMap public API you can use.
And there's also some open source projects--
there's on called G Heat,
to render out these tiles.
Because a HeatMap, once again--
you're probably gonna have to render tiles.
If you use Flash,
you could actually do HeatMaps purely in Flash.
You don't need to render your own tiles,
so we do have a demo of that in the gallery.
This one is a tile HeatMap,
and it's nice--this is a search for pizza.
So this is just to give me a general idea.
If I went to Boston, and I desperately needed pizza,
what general area would I go to?
But, um, the thing to be careful about HeatMaps
is that the user understands what they're looking at here,
and that it's actually useful data.
You know, it could just be that every heat map
looks like this for Boston
because the most amount of restaurants for Boston is there
in the city, right?
So you may look at comparing what data you have
to population data
to make it more clear for the user.
all right, and here's a solution
which is kind of a mix of all the other ones,
which is really, really cool
and something that Google Maps is doing now.
So we were talking about earlier:
it used to be, you do a local search,
you get back those ten markers,
and they represent the top ten results.
But sometimes you want more than that, right?
You're like, "Okay, I searched for pizza."
"I know that there's more than ten pizza places in New York."
So we wanted to have a way of indicating that to the user,
and giving them a better way of visualizing
what their search result really looked like.
So we introduced these things
that we affectionately call pimples,
and they look like little pimples or measles
on top of the map.
And I'll, actually-- I'll just show you
in the browser.
Here we go.
So here I've done a search for Chinese food.
And it's cool because when you look at it,
you can actually-- you can see--
you can tell where Chinatown is.
Chinatown is where the G and the I are.
And that's where the most number of local search results are.
And with these pimples, if I say--
well, so I actually live--
I live right about here.
So I can go and click on one of these
and actually find out that result.
But the thing is that these aren't
actually little markers.
What these are is just a tile
that's been rendered and made clickable.
So the way we make it clickable
is that, at the same time as rendering these tiles,
we passed down some JSON.
And you can look and see the JSON...
So here's some example JSON--
that doesn't really increase it.
But basically, the JSON just contains
information about the clickable pixel bounds,
so we say, all right,
we're passing down these tiles,
and this area's clickable, this area's clickable,
this area's clickable.
So when you do the mouse over event, you can go and query,
"Okay, which pixel bounds am I in right now?"
"Should I change my cursor into a pointer?"
And when somebody actually clicks,
we can go and say,
"All right, what have I actually clicked on?"
"Should--what information should I open up there, right?"
And you could do an AJAX call
to go fetch that information
by some ID that you stored in that JSON.
So this is really nice
because no matter how many search results we have,
we're downloading the same amount of data
but for the user, it's a clickable experience.
So this is how you can kind of mix
being able to visualize lots of information
with having scalable performance.
And we use this for other things, too.
We use this for our photos layer.
And videos,
Wikipedia, web cams.
So this is technically--
if these were done as markers,
the map would just absolutely die,
but these are just combination of clickable tile layers on top.
And we have a demo of this
from on of the developers who's in the audience.
So this is a slightly different way of doing it.
And you can see here, as I mouse over--
we don't do click behavior here--
but, um-- oh, we do?
What happens when I click?
Okay, well, I don't have it in Firebug right now.
But you can see that the mouse cursor is changing
to indicate that these are in fact clickable,
and that you get a very satisfying experience
when you click.
And the way-- [laughs]
The way he's doing this is really, really cool
because, uh...
So in the other example on Google Maps,
we passed on the tiles and then we passed
on a separate JSON.
What he does is he renders the tiles,
and the he attaches cookies to the tiles.
And when he gets each tile,
he just parses out the cookies,
and the cookies contain the information
about the clickable pixel bounds.
So in one single request,
he has all the information needed
to make clickable tiles.
So, John, you should raise your hands
because a lot of people have questions.
Yeah--so I know some of you asked me earlier about this,
so you should talk to John after,
if you're curious for more information
about how he did this.
Okay, so that's a problem with having lots of markers.
So now let's move on to polys.
So the first problem we have
is the same problem we had at GMarker.
It has a lot of features.
GPolygon, GPolyline-- they have lots of features;
they can be, you know, edited.
They're clickable.
They can, um--
they can be geodesic.
We do bounds clipping.
Lots of optimizations that we've done on GPolygon,
and all really catered toward their use on Google Maps, right?
So it may be that your use of polygons
is different from our use,
and you may have to come up with a different solution.
So the first answer, and this is--
it's a very similar story to markers--
is just to do a lightweight polygon class.
So the same way we can extend GOverlay,
and make a lightweight marker,
we can extend GOverlay and make a lightweight polygon.
And so this demo actually comes from
another developer, Mike Geary.
All right, so he just-- he's in the back of the room.
And, this is called Polygonzo,
which is an awesome name.
And you can see what we're using here
is, uh, this is using the Canvas Tag.
And if you guys saw the keynote earlier,
I think they talked about Canvas.
Canvas is awesome.
It's just a way of drawing graphics in the browser.
It's part of HTML 5.
It is in most browsers,
except IE.
But he manages--
this thing hacks on top of VML
to make really, really fast VML.
So, 'cause IE does have VML as a solution,
and he kinda just figured out how to make VML
be as fast as possible.
So it does work in IE as well.
So here we're actually loading in 34,000 points
and about 3,400 shapes,
which is pretty amazing.
And then-- wait, wait for it.
Oh, yeah, that's good.
We'll just take it in for a bit, guys, just take it in.
And I'm sure you guys are thinking, like,
"Oh, I needed animated polys that were rainbow-colored."
But this kinda--
it's kind of silly, but it exemplifies
how--how fast this is.
And this was developed while they were working
on the election maps,
because they needed to be able to visualize
all of the voting districts on top of maps
and do it as fast as possible.
And they didn't want to use tiles
so this is a solution-- they don't need tiles.
And you can see, when we mouse over,
we can actually see, um,
all the information about the county we're mouse overing.
So that's the thing--
JavaScript is actually pretty fast at doing calculations
about what bounds it's inside of.
So really fast at pixel bounds
and even for doing polygonal bounds.
This thing is figuring out on the spot
what we're mousing over.
So that kind of information-- or that kind of processing--
can be done entirely in the client now.
You know, granted, maybe if you do
20,000 places instead of 4,000, maybe you'll get a bit slower.
but a lot of people tend to think
that this is stuff that you need, like,
a spatial server to do
and you have to go send it off
to the Oracle Spatial Database--
that's what I had to do in university.
But it's not really that necessary anymore.
You just do a nice little JavaScript function,
and for the most part it will work.
But even so,
even having this lightweight poly,
you still might have the problem
where your polygons just are too thick,
and have too many points,
and this is actually a pretty common problem.
Because a lot of times, when we get data,
we get it from sources that don't think about the fact
that eventually it might be rendered on a map, right?
So GIS people, they go out,
and they go and, like,
record this pixel, and then record this pixel.
So they come back with massive amounts of points
that represent these regions.
So you can see that Alaska is actually, like,
ten times the amount of points that America is
because Alaska just has this crazy coastline
that goes like that.
So what you want to do is simplify your data
before you render on to the maps.
So you should be simplifying, probably, on the server.
And you can use a couple different programs.
This is a nice online one
that will actually show you interactively, like,
how it's shaping, and show you a couple different algorithms
for simplifying your data.
And there there's some, you know, Python scripts
and what not that will do this for you as well.
So just make sure you're not
trying to render too many points on a map
because often times, your users don't need
all that point information.
And, uh, you should certainly simplify it first.
All right.
Now there's situations where your users
do want the information about all those points,
but they don't want that information
until they've zoomed in, you know, pretty far, right?
So you can see, in this example,
this line is at, you know, some higher zoom level
and as we zoom in, we see more and more points.
And you can do this really easily in the API
using something called encoded polylines.
And so, encoded polylines--
you basically take your information, like,
"Okay, this is my polyline, and here's all the points."
"And the points are gonna display at this zoom level."
And so we'll figure out--
you give us the encoded information,
and we'll figure out, okay, we're gonna show this points,
'cause we're at this zoom level,
and we're gonna show this points 'cause we're at this zoom level.
So that's a nice optimization
because it means that, if the user is at this zoom level,
you can potentially show a lot more polylines
because it's gonna add up to the same amount of points
that you'll have just for that one at the higher zoom level.
So we have documentation about how to write encoded polys,
and there's lots of scripts that can do it for you,
and then, in your database,
it could be a more succinct way of storing your encoded--
your polyline information as well,
because you would simply store it as
a giant string of information.
All right, but saying all that,
you're still gonna have the issue
where you're gonna go pimp it out,
and you're gonna use Polygonzo,
and you're gonna use encoded polylines,
and then you're gonna test it in Firefox and Chrome,
and be like, "Oh, my God, that was the best site ever."
And then you're gonna test it in IE, and you're gonna cry.
So the problem is that when it comes to vector graphics,
the browsers still haven't agreed.
So we have this situation where in the API,
we actually have four different techniques
for rendering polys.
We have VML for IE,
and we have SVG and Canvas.
I don't remember which one we do where
because we change it every week,
and then failing all that we actually have a graphic server
to render tiles out for graphics,
but we don't usually have to use that anymore.
So, it's a sad situation,
and anyone doing anything graphical on the web
knows that it's a sad situation,
and we're also desperately bribing IE
and trying to get them drunk,
and saying, "Hey, Canvas, wahoo!"
But it hasn't happened yet.
So this is the situation with vector graphics on the web.
So there's a couple different solutions for this.
One of them is to give up on the web and use Flash,
which I'm a huge fan of; it's much easier.
So let me show Flash examples.
The great thing about Flash is that,
number one, it works pretty much the same everywhere,
except maybe on mobile phones.
And the other thing is that, um,
it was kind of designed for this kind of thing:
doing graphics and vector graphics.
So it works really well.
So here's a demo using Flash,
and this is visualizing
how San Francisco voted on Proposition 8,
which is kind of an interesting vote to see.
And we can go and change this by one or two choices.
There's a bubble, um, oh, percent.
So it's really nice; it's really fast.
And you can put a fair amount of polys on the map,
and there's actually a blog post which I linked to here
that shows all the countries in the world
and does a comparison using the JavaScript API,
and using the Flash API.
And that's interesting because you can go
and bring it up in the different browsers,
and you'll see--in Chrome, actually, it's pretty similar
because Canvas and Flash have pretty good performance.
But once you open it up in a slower browser like IE 6,
then it all goes to hell.
And Flash doesn't have that issue.
But another solution you can use for JavaScript,
if you're still holding on that the web is gonna get better,
and it should, is to use tile layers.
And this is basically what we do on maps, right?
So thing about our road map tiles
is that they have a huge amount of vector data,
but all that vector is baked into the tiles,
and that's how we get such good performance
because, no matter where you go in the world,
you're always just loading in
the seven tiles that represent that part of the world.
So you can create these tiles layers yourself.
And you can render whatever vector data you have
into those tiles
and basically bake your polygons in there
and then overlay it on top of our tiles.
So here's another demo from John.
And he's just generating these tiles
from his Postgres database,
and, uh,
you can see as we zoom in-- it's just loading more.
Actually, I'll do this in Firebug
so you can actually see the tiles.
So you hid my stuff in view, yes.
So we'll do images, outline images, all images.
So here you can see I've outlined the images.
So you can tell that they're all tiles.
And it's a combination of his custom tiles
with our hybrid upper layer.
And you can see, as you zoom in,
one of these tiles becomes four more tiles.
So this is just an image pyramid.
So if you're creating these tiles yourself,
you just have to have a script that will write out these images
and then create an image pyramid.
So basically the world is divided
into an X-Y-Z grid, um, three-dimensional,
and everywhere in the world you have a tile
representing that grid.
Now you probably don't want to actually pre-render
all the tiles,
especially if you're covering, like, a large area,
like all of America in every zoom level.
So there you probably want to have
on-demand tile rendering,
so that you only create the tiles
for the requested viewport, right?
'Cause it actually is quite a bit of space
on your hard drive
to store tiles for zoom levels 1-21 in the world.
It's like trillions of terabytes and stuff.
That's approximately... number.
So yeah--so actually that's everything I had to say
about performance tips.
So there's a lot here, and a lot of options for you,
using API v3,
combining it with some of the techniques we talked about.
Using API v2 and using some of the techniques.
Using the Flash API.
Lots of things to to that can make for a better experience,
and of course we'll keep working
on trying to bake these things into the API.
So with v3 we baked in
that Static Map optimization
because we knew a lot of people wanted it
but didn't want to go through the effort to implement it.
So where it makes sense,
we're gonna keep trying to do the work for you,
so that you don't have to do
as much of this optimization yourself.
So I just want to talk about
the qualified developer program, again,
for any of you who wasn't in the earlier session.
So this program is to help us find
all the qualified Maps API developers out there
and badge you,
and be able to point people to you.
So in this program you can sign up,
and you can register yourself as a vendor,
and then take a test,
and provide some references,
and indicate if you've done community forum support.
And then we'll see if you qualify,
and we can give you a badge,
and then anyone who's looking for
maps API developers
can go find you in our Vendors Marketplace
and then contact you for work.
So if you are a freelance developer,
please give this a try.
It's fun, taking tests.
I love it.
You love it, too.
So give it a go and please send us feedback about it.
This is the first--
we're rolling this out for the Maps API
before any of our other Google APIs
because the Maps API has traditionally had
a pretty strong freelance community,
and we never really had a good way of recognizing them,
and giving them their--
a spotlight and way for people to find them.
So if it goes well for Maps APIs,
then it goes over the world,
and you can get qualified for everything.
I personally plan on getting qualified tonight.
It should be easy since I wrote half the test.
audience: [laughs]
I felt bad when I failed my own questions, though.
All right, so now we take questions.
If you have questions, you come up to the mic.
Thanks, guys.
audience: [claps]
[clicks tongue]
No questions?
If you--can you come up to the mic and do it?
And I should plug-- there's Ignite.
If you guys have never seen Ignite,
we're doing Ignite at IO.
And Ignite is five minutes, 20 slides, 15 seconds,
It's a very interesting format.
And I'm doing one of the talks
so I'm freaking out a little bit.
But that's at 4:00 in, I think, the room across the way.
So I recommend that four your 4:00 slot,
if you haven't done anything for that yet.
man: Hi, do you know of any implementations
where you have, like, a group of markers on a map,
and it auto-determines what the appropriate zoom level is
so that they're not all bunched up together.
Pamela: So that's, basically-- you can stay up.
That would basically be marker cluster,
like, it figures out-- Oh, actually, no, no.
So we have something called MarkerManager,
and what MarkerManager does is, it says--
you give it batches and you say,
"Okay, I want these markers at this zoom level,
and these markers at this zoom level."
But the thing is, there, you have to pre-decide the batches,
but somebody for the Flash API
wrote something on top of the Marker Manager,
which will automatically figure out,
like, nice zoom levels for that.
So I think he called it multi-level MarkerManager,
but I can ping you the link after.
man: Thanks.
Pamela: Yeah, so that doesn't do clustering.
It just does random, like--
oh, there's a lot here so we're not gonna--
we're not gonna show all of those at this zoom level.
man: I have close to 4,000 markers,
and a layer of polygon.
I want both of them clickable.
Pamela: Okay.
man: So far, I'm using the XML parsing
so that I can hide it, you know, or show it whenever I want.
Pamela: Yep.
man: Now, what's happening here
is that every time I click on the link,
the parsing is going on in the background,
and I don't want that.
How do we stop it?
It's taking forever, so.
Pamela: Um, what is it parsing when you click?
man: It's parsing the XML file.
It just has the lat-long information,
and just a description, that's all.
Pamela: Okay, well, the first thing I would recommend that
is instead of using XML, I would use JSON,
since it's natively supported in JavaScript.
So you'll get a slightly faster
parsing performance, there.
man: I see.
Pamela: And then--JSON, you can make pretty compact.
You can really make your keys be really short
and stuff like that.
So I recommend JSON just as the data transfer format.
man: Okay.
Pamela: And as for--
I don't know what your exact setup looks like,
but I would look at how much data you're downloading
and how much you're parsing,
and whether maybe you can segment it differently.
And maybe--I don't know what you're doing exactly,
but you could do more efficient stuff
if you only load in the data for approximately that bounds
or something like that.
man: Yeah, unfortunately, we don't have that option.
We want to see all the 3,000 markers at the same time.
And then as we move in, you know,
the other 2,000 kick in.
Okay, so I'll try the JSON for that.
Pamela: Yeah, try JSON with some of the things
we showed here as well.
man: Okay, and the second question is
do you have thematic mapping support for AP--uh, for maps?
I know they recently came out with one for Google Earth,
which was like, something, last week or--
Pamela: Yeah, yeah.
So yeah, this guy, this developer, Bjørn Sandvik,
from the thematic mapping blog.
He made it--he used the visualization API
with the Google Earth API to make it really easy
to do thematic mapping.
Just--I think he does it country-base.
So you can make a spreadsheet that has a bunch of countries,
and codes,
and then it will go on plot them on Google Earth,
doing different visualization techniques.
So that's just something a developer wrote.
We in-- I'd say, in the APIs,
we really haven't baked in
any sort of thematic mapping.
But lots of people have done it on top of it.
So I would love for us to bake it more in,
to make it a bit easier to do thematic mapping,
'cause it is hard right now.
But there's a fair amount of data out there
and, of, geometry data,
'cause the first thing you need is geometry data.
And in the group we have...
long--that's not what I'm searching for.
So we have--
well, we have a bit easier to use--not that one.
This one: GIS Data.
This is a long list of data sets
that we've kind of collected,
so UK boundaries, world data sets.
This one's really cool: dyne geometry.
They'll actually give you--
they give you the encoded polylines
and a JSON for all these regions in the world.
And they also offer a web service as well
to give back the geometry.
So there-- it's certainly--
It does require a bit of effort
to, you know, find that data
and then decide how you want to render it on the map.
But there's nothing stopping you from doing it.
man: Okay, okay, and the last question would be
is there a JavaScript support in KML right now?
My objective is to--
when I'm clicking on a small href link,
it should pop up a window,
rather than just popping up a whole--
rather than redirecting it to a completely new blank page
or some page.
I just want to limit that to a pop-up window.
Pamela: Right, so, as for KML support in the APIs,
in the JavaScript API v2, we have this class
called GeoXml,
and that takes a KML file and renders it on the map.
But we don't provide--
it doesn't provide any more customization
on top of it.
It's just putting on the map,
and then however we render it is how we render it.
And you can't control it.
So a lot of people have written
open source extensions for parsing KML,
so there's E GeoXml, and there's GeoXml.
And these will read in the file and display it,
and then you can customize more
of how that KML is displayed.
But the thing there is that
it's rendering it using native GMarker and GPolyline.
So you'll still suffer from performance
if your KML file is quite large.
So you could look at combining
E GeoXml with, maybe, Polygonzo or Marker Light
if you need to have a lot of geometry in your file.
man: Okay, I see. All right, thank you.
Pamela: Yup.
man: I got a question regarding the Redfin solution.
So, yeah, you're not using DOM nodes,
and you're kind of breaking up the DOM string
and then you are using innerHTML,
but ultimately it's still DOM elements,
and then anytime that you're gonna be panning the map,
it is still gonna be slow.
Are you doing anything to work around that,
or is your solution basically just to solve the drawing
and not worry about the panning and stuff like that.
But it is part of the mapping faction.
Sasha: So, if you don't mind. Pamela: Yeah.
Sasha: Yeah, so, clearly panning is also a problem.
I mean, most browsers-- 500 divs is not that bad...
is not particularly bad.
And we spend a lot of time worrying about the redraw.
The first draw is gonna be the worst for us,
but we do a lot of stuff of, like,
keeping an array of pointers to all those DOM nodes.
based on IDs.
And, you know, there's lots of
interesting things you can do where you say,
okay, well, those ten went off-map,
and I want--put ten onto the map.
Okay, instead of taking out those ten DOM nodes
and putting ten DOM nodes back in,
or redrawing it all,
you can say, okay, well just change the CSS style,
so I get a different CSS background image,
and give them a different ID,
or swap out their ID.
And now all of a sudden, you know,
I didn't actually have to do--
I didn't have to add or subtract from the DOM,
which is super-expensive.
You can also, like, let's say
you know, half of the markers went off the map.
Sometimes it's better just to go through
and display NONE nodes,
rather than ripping them out of the DOM.
And then, you know, we put in heuristics for, okay,
well, but if you know, sometimes we put in heuristics--
we've tweaked this a million times.
But, heuristics for things, like,
okay, well, if I'm taking out 90% of the things on the map,
I should probably just take the whole div
that contains all of them out,
and just re-draw.
And so those are a couple strategies we've used,
and actually, to be honest,
I don't remember which ones we're using right now
because we've cycled through, I think, all of those.
And I think some of those we're still using,
but it's a matter of
think of those, test them, think of those, test them.
Does that help?
man: Yeah, and, just a kind of general question.
Have you guys run into this IE, of course, issue
where there's an HTML DOM size limit of 175,000 pixels?
Sasha: I have not. Pamela: No.
Sasha: I have never run into that.
man: You guys are really lucky if you haven't.
All right, thanks.
Sasha: Sweet!
Pamela: We have other IE issues.
man: My question just kinda has to do with G Unload.
v2 kind of introduced--helped with all the circular references
and all that, but I see a kind of absence in v3,
so, improvement?
Pamela: So, yeah, that's an improvement.
'Cause we realized we could just do G Unload ourselves.
'Cause we had you put G Unload on the body on Unload.
But it's like, well, why are we making them do that?
We can do that ourselves.
So we do all of that clean-up ourselves.
man: Cool. Pamela: Yeah.
We actually had it, like, a month ago,
and then we were, like, this is silly.
We don't want to make developers do it.
So you notice in the v3, like, we've gone through and, like,
everything that makes it into v3 API
we've kind of analyzed it to death,
and fought,
and decided which things really belong in this API,
and which things we can do for you and stuff.
man: Sorry, I came in late.
About GMAP-3.
Are all the features of GMAP-2
gonna be supported in GMAP-3?
You just change the architecture
to optimize the performance, right?
Pamela: Yeah, so--
I should--we didn't really mention that it's--
did you say it's MVC architecture?
Marcelo: I didn't.
Pamela: Okay, so, we're doing an MVC architecture,
which makes it easier for us to bring new things in
because it makes it really, really trivial to modularize.
And there will be more information about that
in Susannah's talk tomorrow.
But, basically, we're going to look at v2 and v3
and look at the usage for the features in v2,
and figure out which things should be baked into v2
and also figure out which things we can simply open source,
and put it into its own library.
So we're gonna have a bit more
of an official story on extensions,
and maybe have slightly more official extensions as well.
So stuff that we didn't maybe think is necessary
to put into that main core,
but we wanna make it really easy for people
to integrate with their maps.
So eventually, everything should be supported
in some way,
as long as it was something
that people actually used in v2.
We actually did have one class in v2
that we discovered this year
had never been used.
man: Which one?
Pamela: It was...
gXML...transform... GXslt?
man: Oh, yeah, that's transform.
Pamela: Yeah, it had a bug in it,
so it wasn't usable.
So that kind of class--
For two years, no one said anything, right?
That kind of class we would probably not have it
in this thing, right?
And the thing also to think about
is the Maps API came out
before there were many JavaScript APIs on the web.
So there's a lot of stuff we put in the Maps API,
like, how to create dragable objects,
how to do XML HP request,
that's really not necessary to have in a Maps API.
We just did it because people didn't have any other options.
Now, most people use, like jQuery, Prototype, whatever.
So it's silly for us to replicate
the kind of general AJAX-y things
that those things do.
So you notice that we probably wouldn't put classes like that
into a Maps API.
man: So there's not gonna be a GMAP Light, right?
It's gonna be GMAP-3 for both mobile and desktop.
Pamela: It's quite light.
It is light, yes. [laughs]
man: Looking forward to it.
Pamela: Okay.
All right.
Cool, so you guys can come to Ignite now...sweet.
All right. Thank you, guys.
Sasha: Thank you. Marcelo: Thank you.