Addendum: if you specify the user's language (and optionally region) when you load Maps API v3, the bootstrap does not include HTTP response header "Vary: Accept-Language". We recommend specifying the language when your site knows the user's language, as this reduces latency for some users. For example see this demo: http://code.google.com/apis/maps/documentation/v3/examples/map-language.html For more information on localization, see this section of the documentation: <http://code.google.com/apis/maps/documentation/v3/examples/map-language.html> http://code.google.com/apis/maps/documentation/v3/basics.html#Localization
Cheers Ben On Mon, Feb 1, 2010 at 7:39 PM, Ben Appleton <apple...@google.com> wrote: > I've spent some time looking further into the Google Page Speed score for > Maps API v3. I'm using the v3 "hello world" example for reference: > http://code.google.com/apis/maps/documentation/v3/examples/map-simple.html > Attached is a screenshot of Page Speed with each column collapsed. I'm > loading the above page in FireFox 3.6, waiting for everything to download, > then turning on page speed. I will address each Page Speed rule in turn > below. > > ------------------ > *Serve resources from a consistent URL (red)* > The following resources have identical contents, but are served from > different URLs. Serve these resources from a consistent URL to save 12 > request(s) and 2.1KiB. > > - http://mt0.google.com/vt/v=ap.116&hl=en-US&x=236&y=154&z=8&s=Galile* - > map tile* > - http://mt2.google.com/vt/v=ap.116&hl=en-US&x=236&y=155&z=8&s=Galileo* - > map tile* > - ... > > > These tiles consist entirely of ocean. Page Speed will only report this > rule if your viewport contains tiles of constant color, such as these blue > ocean tiles. Each ocean tile is 230 bytes. > > This is a chicken-and-egg problem: for the browser to download these tiles > from the same URL it must know these are ocean tiles. If the browser knew > these were ocean tiles it would not need to download them, since it could > use a blue div. So, I consider this a false positive from Page Speed. > > ------------------ > *Minimize DNS lookups (yellow)* > The domains of the following urls only serve one resource each. If > possible, avoid the extra DNS lookups by serving these resources from > existing domains. > > - http://maps.gstatic.com/intl/en_us/mapfiles/api-3/27a/main.js - *JS* > - http://maps.google.com/maps/api/js?sensor=false - *API bootstrap* > - > http://code.google.com/apis/maps/documentation/v3/examples/map-simple.html > - > *Test page* > > > ------------------ > The first item is the API JS, loaded from maps.gstatic.com. But > maps.gstatic.com is also used to load the JS modules: common.js, > mapview.js, util.js, controls.js, and stats.js. Likewise, the second item > is the Maps API v3 bootstrap, fetched from maps.google.com. But > maps.google.com is also used for service requests, such as the copyright > and authentication services. I suspect Page Speed flags the main JS module > and the bootstrap because they are requested before page load, whereas the > remaining modules and service requests come after the page load. But that > is intentional: Maps API v3 loads as little as possible upfront to minimize > the time to show a map. > > We could save 1 DNS lookup by merging maps.google.com and maps.gstatic.com. > However maps.google.com serves cookies whereas maps.gstatic.com does not. > So merging these domains would bloat the HTTP request headers for our > static files. This is not worth saving 1 DNS lookup. > > The third item is the test page. Usually the API is loaded on to a > developer's site, and the developer would load other resources from their > site, so Page Speed would not flag the containing page. > > ------------------ > *Serve static content from a cookieless domain (yellow)* > Serve the following static resources from a domain that doesn't set > cookies: > > - http://mt1.google.com/vt/v=ap.116&hl=en-US&x=235&y=153&z=8&s=Ga* - > map tile* > - http://mt3.google.com/vt/v=ap.116&hl=en-US&x=235&y=154&z=8&s=Gal* - > map tile* > - ... > > ------------------ > This is a good suggestion: our tile servers could be on domain other than > google.com. I'll follow this up. > > ------------------ > *Leverage browser caching (green)* > The following resources specify a "Vary" header that disables caching in > most versions of Internet Explorer. Fix or remove the "Vary" header for the > following resources: > > - http://maps.google.com/maps/api/js?sensor=false - *API bootstrap* > > The following cacheable resources have a short freshness lifetime. Specify > an expiration at least one month in the future for the following resources: > > - http://maps.google.com/maps/api/js?sensor=false - *API bootstrap* > > *Non-scoring information* > To further improve cache hit rate, specify an expiration one year in the > future for the following cacheable resources: > > - http://mt0.google.com/vt/v=ap.116&hl=en-US&x=232&y=152&z=8&s=* - map > tile* > - http://mt0.google.com/vt/v=ap.116&hl=en-US&x=232&y=154&z=8&s=Ga* - > map tile* > - ... > > The following resources are explicitly non-cacheable. Consider making them > cacheable if possible: > > - > > http://gg.google.com/csi?v=2&s=mapsapi3&action=apiboot&rt=jl.582,mjs.582,mc.611,mb.1274,...<http://gg.google.com/csi?v=2&s=mapsapi3&action=apiboot&rt=jl.582,mjs.582,mc.611,mb.1274,vt.2855,prt.2855,plt.2826,mt.2857&size=1400x601&maptype=m> > * - latency logging* > - > > http://maps.google.com/maps/api/js/AuthenticationService.Authenticate?url=http%3A%2F%2Fcode.google.c...<http://maps.google.com/maps/api/js/AuthenticationService.Authenticate?url=http%3A%2F%2Fcode.google.com%2Fapis%2Fmaps%2Fdocumentation%2Fv3%2Fexamples%2Fmap-simple.html&callback=_xdc_._1g54utkgj> > * - authentication* > - > > http://maps.google.com/maps/api/js/CopyrightService.GetCopyrightString?viewport=b&southwest=b&am...<http://maps.google.com/maps/api/js/CopyrightService.GetCopyrightString?viewport=b&southwest=b&lat=-35.74791030752601&lng=146.79878515625&southwest=e&northeast=b&lat=-33.02392621412177&lng=154.48921484375&northeast=e&viewport=e&zoom=8&map_type=0&language=en-US&callback=_xdc_._0g54utjvf> > * - copyrights* > > ------------------ > The API bootstrap includes 2 HTTP response headers of interest here: > "Cache-Control: public, max-age=600" and "Vary: Accept-Language". Public > caching allows intermediate proxies and internet service providers (ISPs) to > cache the API bootstrap, which reduces the round trip time (RTT) for your > browser to load the bootstrap from a cold cache. "Vary: Accept-Language" > prevents responses for 1 language being served to users who prefer other > languages. > > Unfortunately a popular browser does not cache resources with the "Vary: > Accept-Language" header, which is why Page Speed flags this as a potential > issue. That browser will request the API bootstrap anew each time, though > the request may be satisfied by their ISP or a caching proxy which would > reduce their RTT. Users of other browsers will see a net win in latency, as > the first load may be satisfied by a proxy while subsequent loads will be > satisfied by their browser's cache. This was a design choice to minimize > average latency across all users, and we'll be keeping an eye on browser > behavior to see if this is a good tradeoff. > > Page Speed also flags the API bootstrap as having a short freshness > lifetime (10 minutes, versus the recommended 1 month). The API bootstrap > contains configuration data which changes over time, such as the latest API > version, tile versions, and so on. If the API bootstrap were cached for a > month we could only release new tile sets and JS versions each month, so > that is not an option. Even though 10 minutes is short, the API bootstrap > is downloaded tens of thousands of times every 10 minutes, so caching > proxies may still serve the bulk of API bootstrap requests. > > Page Speed suggests setting the expiration date for our map tiles 1 year in > the future. They are currently served with "Cache-Control: public, > max-age=22222222", or 8.5 months. The difference is not significant. > > The last 3 resources are listed as non-cacheable: > > 1. Latency logging: while the API loads we measure time to load the API > javascript, map tiles, and so on. Well after the page has finished loading > we log these statistics back to the server. We analyze these logs to > measure the effect of latency optimizations and to plan future > improvements. > 2. Authentication: the authentication request replaces the API key > system from Maps API v2. The key system was cumbersome as it tied a site > to > 1 domain, keys were long which bloated request URLs, and keys added entropy > to request URLs which made caching ineffective. The authentication service > is intentionally not cacheable so that we can quickly shut down a site that > contravenes our terms. > 3. Copyrights: the copyrights service tells the API which data provider > attributions to display for the current map viewport. The request contains > the exact map viewport; so much entropy makes caching ineffective. It's > possible to quantize the user's viewport to reduce request entropy, but > making the copyright appear a few milliseconds faster does not seem like a > big win for users. > > ------------------ > *Leverage proxy caching (green)* > Due to a bug in some proxy caching servers, the following publicly > cacheable, compressible resources should use "Cache-Control: private" or > "Vary: Accept-Encoding": > > - http://maps.google.com/maps/api/js?sensor=false - *API bootstrap* > > Resources with a "?" in the URL are not cached by most proxy caching > servers. Remove the query string and encode the parameters into the URL for > the following resources: > > - http://maps.google.com/maps/api/js?sensor=false - *API bootstrap* > > > ------------------ > As discussed above, we believe that serving the API bootstrap as > "Cache-Control: public" improves the average latency across all users, but > we'll be keeping an eye on latency statistics to see if this is a good > tradeoff. > > We know that resources with "?" are not cached by many caching proxies; > indeed this is why our tile URLs do not contain "?". We could allow sites > to instead write http://maps.google.com/maps/api/js/sensor=false, but > that's unusual and may confuse some developers. So this is a tradeoff > between ugly URLs vs improving caching for some proxies. > > ------------------ > *Minify HTML** (green)* > Minifying the following HTML resources could reduce their size by 152B (19% > reduction). > > - Minifying > > http://code.google.com/apis/maps/documentation/v3/examples/map-simple.htmlcould > save 152B (19% reduction). > > ------------------ > This is our test page, which is designed to be readable. Individual sites > can optimize their pages for speed to prevent Page Speed from flagging this > issue. > > ------------------ > *Minify JavaScript** (green)* > There is 130.1kB worth of JavaScript. Minifying could save 117 bytes (0.1% > reduction). > > - Minifying http://maps.google.com/maps/api/js?sensor=false using JSMin > could save 88 bytes (2.3% reduction). See minified version. > - Minifying > http://maps.gstatic.com/intl/en_us/mapfiles/api-3/27a/main.js using > JSMin could save 29 bytes (0.1% reduction). See minified version. > > ------------------ > The Maps API v3 JS is already minified by Google's Closure Compiler. > > ------------------ > *Optimize images** (green)* > Optimizing the following image resources could reduce their size by 1.4KiB > (25% reduction). > > - Optimizing > http://maps.gstatic.com/intl/en_us/mapfiles/mapcontrols3d5.png could > save 288B (10% reduction).* - control sprite* > - Optimizing > http://mt3.google.com/vt/v=ap.116&hl=en-US&x=235&y=156&z=8&s=Galilcould > save 77B (35% reduction). > * - map tile* > - ... more tiles ... > > ------------------ > We'll look into these savings. > ------------------ > > To sum up: Maps API v3 should load tiles from a cookieless domain, we'll > take another look at the effect of our HTTP response headers, and we'll > check the compression of our PNGs. > > - Ben > > > > On Fri, Jan 29, 2010 at 12:32 PM, Austin <austinhu...@gmail.com> wrote: > >> I tried to reply to an older post directly, but for some reason it's >> not letting me (http://groups.google.com/group/google-maps-js-api-v3/ >> browse_thread/thread/f4a1f4d703267d48/9e8fcf770d1aed2b?lnk=gst&q=Page<http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/f4a1f4d703267d48/9e8fcf770d1aed2b?lnk=gst&q=Page> >> +Speed+score#). So here's my reply to that thread: >> >> >> I'm having similar issues as Ed. Is there any update on this? Is >> there a way to only load v3 on a page after the dom has loaded if a >> user executes a specific action, such as clicking on a "Show Map" >> button? I've tried multiple different methods to post-load the js >> (http://maps.google.com/maps/api/js?sensor=false) so it only loads on >> a certain user action in hopes of not getting my Page Speed score >> docked from all the Google Maps files, but each time the >> document.write in it overwrites the main page content. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Google Maps JavaScript API v3" group. >> To post to this group, send email to >> google-maps-js-api...@googlegroups.com. >> To unsubscribe from this group, send email to >> google-maps-js-api-v3+unsubscr...@googlegroups.com<google-maps-js-api-v3%2bunsubscr...@googlegroups.com> >> . >> For more options, visit this group at >> http://groups.google.com/group/google-maps-js-api-v3?hl=en. >> >> > -- You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group. To post to this group, send email to google-maps-js-api...@googlegroups.com. To unsubscribe from this group, send email to google-maps-js-api-v3+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.