Google Maps API v3: Developing for Mobile Devices

April 30, 2013 Update: Post and template updated to include a more modern application cache loading script as well as utilizing my GeolocationMarker code and the latest Maps API v3 options.

Developing a map for mobile devices presents unique challenges. Not only must your user interface work on a small screen and be optimized for touch, but your map needs to load fast.

Note: This article is about maps for iPhone and Android devices. Many of the techniques here are optimized for HTML5 browsers and will not work in Internet Explorer or older browsers. While techniques exist to support similar functionality on other browsers, they are beyond the scope of this article.

Mobile Template

Must go faster

Speed to the user can be a tricky thing to measure. Do you measure until when your map, custom layers, markers and location are fully loaded? Or do you measure until the user can first interact with the map? Whatever the choice, it is important to provide feedback to the user so that they can at least see progress.

Delay loading the Maps API

Script tags block page rendering until they are completely downloaded and processed. This can be a significant wait on slower devices when loading the Maps API during which time the user won’t see any progress. To allow your page to load first, dynamically add the Maps API on the DOMContentLoaded event. When you use this technique, you’ll need to add a callback parameter to the script source to know when the API has finished loading.

document.addEventListener('DOMContentLoaded', function () {
    var element = document.createElement('script');
    element.src =
        'http://maps.google.com/maps/api/js?sensor=true&callback=Initialize';
    element.type = 'text/javascript';
    var scripts = document.getElementsByTagName('script')[0];
    scripts.parentNode.insertBefore(element, scripts);
}, false);

Delay loading map customization scripts until the Maps API loads

Wait until the map has loaded to add custom layers, markers and other data. The tilesloaded event is a good place to start adding your data. This allows the user to see even more of the map load instead of waiting until everything is done. If your map script is in an external JavaScript file, you can dynamically add it right after initializing the map.

function Initialize() {
    var MapOptions = {
        zoom: 15,
        center: new google.maps.LatLng(37.20084, -93.28121),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        sensor: true
    };
    map=new google.maps.Map(
        document.getElementById("map_canvas"), MapOptions);
 
    //Delay customizations until the map has loaded
    var element = document.createElement('script');
    element.src = 'template.js';
    element.type = 'text/javascript';
    var scripts = document.getElementsByTagName('script')[0];
    scripts.parentNode.insertBefore(element, scripts);
}

HTML5 offline storage

This is basically caching on steroids. This has been covered elsewhere, but it should be mentioned that this alone makes a HUGE difference for return visits. There are a couple of things to keep in mind when developing a cache-manifest file:

  • Every URL used in the site must be specified in either the CACHE or the NETWORK sections. The CACHE section takes specific urls while the NETWORK section takes URL prefixes.
  • FireFox will cache this seemingly permanently. To clear it, remove your site from the Offline Storage section of the options (under Advanced – Networking). Chrome treats this similarly (only available in the 5.0 and later versions). Application cache usage is temperamental. See my post on the challenges of using the application cache with an external API.
  • All map customizations must be done by JavaScript and not through a server-side mechanism since the page will be cached offline.

Sample CACHE-MANIFEST file:

CACHE MANIFEST
/examples/template.htm
/examples/template.css
/examples/template.js
http://missouristate.info/images/2010/loading.gif
http://missouristate.info/images/2010/map/gpsloc.png
NETWORK:
http://maps.gstatic.com/
http://maps.google.com/
http://maps.googleapis.com/
http://mt0.googleapis.com/
http://mt1.googleapis.com/
http://mt2.googleapis.com/
http://mt3.googleapis.com/
http://khm0.googleapis.com/
http://khm1.googleapis.com/
http://cbk0.googleapis.com/
http://cbk1.googleapis.com/
http://www.google-analytics.com/
http://gg.google.com/
http://csi.gstatic.com/

Note: The URLs listed above are subject to change without notice. When using the Google Maps API via SSL there are slightly different versions of the addresses.

Follow industry best practices

Use the Google Page Speed tool to help optimize your site. While the suggestions are relevant to any site, they make a much bigger impact on mobile devices due to the high latency connections and device processor/memory constraints.

User interface

Not only must your map function on a small screen, but there is a wide variety of screen sizes among devices.

Dynamic map height

You want the map to fill the whole screen minus the space for any header/footer. You can use a CSS technique with conflicting absolute positions to avoid having to calculate height in JavaScript. This method will properly handle device rotation as well.

<div id="map_canvas"
    style="position:absolute;top:30px;bottom:50px;left:0;right:0;"></div>

Show a progress indicator

Lack of  feedback will frustrate your users. It’s rather simple to display a progress indicator to let your users know that the map is actually loading. Adding an overlay div to indicate loading is an easy way to show this. You can disable the loading div in the tilesloaded event.

Use the special link and meta tags

Both Android phones and the iPhone support a number of link and meta tags for sites which are designed to function as an application. Here’s a list of the one’s most applicable to a map:

Tag Name/Rel Value Supporting Device Note
link apple-touch-icon Url of PNG Icon iPhone and Android Android doesn’t add gloss to icons
link apple-touch-icon-precomposed Url of PNG Icon iPhone and Android The iPhone won’t add gloss to this icon
link app-touch-startup-image Image to display while loading iPhone Only shows when the site has been saved then launched from the home screen.
meta apple-mobile-web-app-capable “yes” iPhone Indicates that the site is designed to function as a standalone application (launched from the homescreen) without browser chrome.
meta viewport initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0 iPhone and Android Indicates that the browser should display the site without scaling and disable zooming the entire page since the map handles zooming.

Use high resolution images

Newer mobile devices (and now even laptops and desktops) come with high-density displays. To make full use of these, your map needs to use high resolution graphics. I have found that using CSS selectors based of the device-pixel density to be unreliable as there doesn’t seem to be a common meta viewport tag that will correctly report the density across all browsers. Instead, I’ve found it is just easier to make all images twice the size and scale them to 50% via CSS. Map markers and overlays can use a similar technique using the scaledSize property of the Icon object. Unfortunately at this point in time there is not a way to use high resolution icons in KML or Fusion Table Layers.

About Chad Killingsworth

Chad Killingsworth is the assistant director and technical lead for the office of web & new media at Missouri State University.
Follow me on twitter
This entry was posted in Technical, Web and New Media and tagged , , , . Bookmark the permalink.

3 Responses to Google Maps API v3: Developing for Mobile Devices

  1. Jason says:

    Thanks for documenting this Chad! I’ve been following along in the Google Maps API v3 list so having this in a semi-permanent place is great. Good work with the Missouri State mobile app. It works great.

  2. This is very useful indeed! I think that google maps in mobile phones is such a great tool! Thank you for giving us a detailed explanation on how it works.

  3. Pingback: Summer Reading Fun « Mapping Blog