Optimizing based on connection speed: using navigator.connection on Android 2.2+

September 14th, 2010

Introduction

A little while back this post made the rounds, which took us on a journey through some of the new features introduced in the browser in Android 2.2 Froyo. Among the most overlooked features are the file upload functionality (you can upload photos from your browser now! But we’re still waiting on iPhone to support this…) and a little-known JavaScript addition to the Browser Object Model (BOM) in the form of navigator.connection. Let’s take a peek at its contents:

// contents of navigator.connection object
{
  "type": "3",
  "UNKNOWN": "0",
  "ETHERNET": "1",
  "WIFI": "2",
  "CELL_2G": "3",
  "CELL_3G": "4"
}

This is data taken from a Nexus One running on a 2G network, so you can see that the type is set to 3, which corresponds with “CELL_2G”. In other words, this phone runs on a slower network, so from a performance perspective, you probably want to consider delivering a lower-bandwidth experience.

So how exactly do we target this?

The code

The purpose of this code is to first find the connection speed, and then add a class to the html element based on this connection. The goal is to be able to target these connections with CSS, so the right content is delivered to the right connection:

.highbandwidth .logo   { background-image:url('logo-high.jpg'); }
.mediumbandwidth .logo { background-image:url('logo-medium.jpg'); }
.lowbandwidth .logo    { background-image:url('logo-low.jpg'); }

And here’s the JavaScript:

var connection, connectionSpeed, htmlNode, htmlClass;

// create a custom object if navigator.connection isn't available
connection = navigator.connection || {'type':'0'};

// set connectionSpeed
switch(connection.type) {
  case connection.CELL_3G:
    // 3G
    connectionSpeed = 'mediumbandwidth';
  break;
  case connection.CELL_2G:
    // 2G
    connectionSpeed = 'lowbandwidth';
  break;
  default:
    // WIFI, ETHERNET, UNKNOWN
    connectionSpeed = 'highbandwidth';
}

// set the connection speed on the html element, i.e. <html class="lowbandwidth">
htmlNode = document.body.parentNode;
htmlClass = htmlNode.getAttribute('class') || '';
htmlNode.setAttribute('class', htmlClass + ' ' + connectionSpeed);

Give the user control!

Just as it’s a good practice to give the user a link to the full desktop version of the website, if you’re going to deliver different content based on different connection speeds, then it’s highly advisable to give the user full control.

So give them control! You can provide something like the following:

Mobile | Desktop

Bandwidth: High | Medium | Low

  1. Hey David,

    I don’t suppose you know of a way to enable this functionality on applications that are using the WebView? When I query navigator.connection in my PhoneGap app I always get type 0.

    Thanks…

    Simon

  2. Jon Raasch says:

    @Simon
    Looks like PhoneGap has something a little different built in for this:
    https://github.com/shazron/phonegap-docs/commit/d0e6504c427fb881f7be7e2a625694619e9f95b6

    Just stumbled across that researching navigator.connection, but it looks like it might be what you’re looking for.

  3. [...] if mobile bandwidth is detected (like 3G), the low-resolutions stay in place thanks to the new navigator.connection first seen in Android [...]

  4. [...] profitieren, und zwar in Form hochaufgelöster Bilder und Webseiten. Hier, so Brad Frost, komme navigator.connection ins Spiel: Ähnlich wie beim responsiven Webdesign mit CSS Media Queries, mit deren Hilfe sich [...]

  5. [...] navigator.connection看来有所帮助,但是基本的网络类型(EDGE, 3G, wi-fi, 等)并不能代表全部。在巴士上或者星巴克里面,一个共享的网络很有可能比3G网络更慢。 [...]

  6. [...] navigator.connection看来有所帮助,但是基本的网络类型(EDGE, 3G, wi-fi, 等)并不能代表全部。在巴士上或者星巴克里面,一个共享的网络很有可能比3G网络更慢。 [...]

  7. [...] navigator.connection seems to help, but the basic types of networks (EDGE, 3G, wi-fi, etc.) and do not represent all. On the bus or Starbucks inside a shared network is likely to be more than the 3G networks slow. [...]

  8. [...] a web. With any server-side fortitude to a bandwidth problem still distant off on a horizon, navigator.connection will turn even some-more profitable in a meant [...]

  9. [...] the web. With any server-side solution to the bandwidth problem still far off on the horizon, navigator.connection will become even more valuable in the mean [...]

  10. [...] the web. With any server-side solution to the bandwidth problem still far off on the horizon, navigator.connection will become even more valuable in the mean [...]

  11. [...] navigator.connection看来有所帮助,但是基本的网络类型(EDGE, 3G, wi-fi, 等)并不能代表全部。在巴士上或者星巴克里面,一个共享的网络很有可能比3G网络更慢。 [...]

  12. Paul d'Aoust says:

    Correct me if I’m wrong, but don’t most web browsers load all assets referred to in the CSS file(s)? Therefore, I believe that this snippet will load all three… I believe the correct method would be to use JS to load the asset by applying it to the element (either with src attribute or inline style, depending on your preference for displaying logos).

    Unless mobile browsers are getting smarter and lazy-load assets only when a CSS rule matches an element on the page — in which case I stand corrected! I just remember that this was a point brought up in an article I read about the troubles encountered when the author tried to implement responsive images.

  13. [...] a recent project I was looking for a way to test online/offline state, I came across Using navigator.connection in Android. Which is a blog post covering the Network Information [...]

  14. [...] navigator.connection – Optimizing based on connection speed: using navigator.connection on Android 2.2+ (Via @m4rkmc) [...]

  15. [...] navigator.connection看来有所帮助,但是基本的网络类型(EDGE, 3G, wi-fi, 等)并不能代表全部。在巴士上或者星巴克里面,一个共享的网络很有可能比3G网络更慢。 [...]

  16. Sebastian says:

    Its Easy to see if the Browser loads your Files. I created a php file which says its a picture and added my Email adress. If you get a Mail, the Browser requested your file.
    My experience is, that Browsers dont load overwritten Statements or display:None Elements.

  17. [...] They shouldn’t be punished with downloading a massive Retina-ready image. That’s where navigator.connection comes into play, but even the basic connection types don’t give the whole picture of the user’s [...]

  18. [...] navigator.connection looks like it can help, but basic types (EDGE, 3G, wi-fi, etc) don’t tell the whole story. A shared wi-fi network on a Bolt Bus or Starbucks can easily run slower than a 3G network. [...]

  19. Nuno says:

    This looks absolutely perfect. All these tiny details are made with lot of background knowledge. I like it a lot. Sense helpful ;)

  20. Moin Uddin says:

    Wow..
    Really helpful to web devs. Thank for writting. :-)

Leave a Reply