A quick look at the Network Information API
UDPATE : this article is now out of date. Please read the latest spec at http://w3c.github.io/netinfo/ and a very interesting summary of the use cases at http://w3c-webmob.github.io/netinfo-usecases/
UPDATE : the W3C working draft has been updated and the categories (unknown
, ethernet
, wifi
, 2g
, 3g
, 4g
and none
) are gone. For now it's bandwidth in Megabytes/second as detailed below but doubts are expressed about the viability of that with the possibility of very-slow
, slow
, fast
and very fast
mooted.
If you were to ask developers with an interest in mobile today what one feature they would like above all others, there’s a good chance a lot of them would say bandwidth detection.
The Network Information API represents the first steps down that road, and there is a working draft at the W3C dated June 2011. As we can see from Maximiliano Firtman‘s excellent mobile support tables, it is supported on Android 2.2 and up, and on the Kindle Fire’s Silk browser.
As APIs go it couldn’t be much simpler — we just get the value of navigator.connection.type
which will be one of unknown
, ethernet
, wifi
, 2g
, 3g
, 4g
and none
. In practice Android deviates from the specification and returns 0, 1, 2, 3 or 4. (I don’t know what Silk does, but it’s a custom Android so it’s as likely as not that it’s the same).
Value | Connection type |
---|---|
0 | UNKNOWN |
1 | ETHERNET |
2 | WIFI |
3 | CELL_2G |
4 | CELL_3G |
navigator.connection.type
and their corresponding network types in the Android BOM.So a simple alert(navigator.connection.type);
will give us something like the screenshot shown in figure 2. Demo (Android only)
That’s the current version of the Network Information API as it exists in the wild today, and although not totally useless it doesn’t give us much to go on. We can really only make inferences from CELL_2G and NONE. We know 2g is definitely slow — ethernet, wifi and 3g can be fast or slow. As far as NONE is concerned we could maybe listen for clicks on links/buttons and present our own “Network down” message instead of a browser or router error page if there is no network.
Personally, I wouldn’t be comfortable drawing any conclusions about network speed if the returned value represented ethernet, wifi or 3g but I might consider something like:
if(navigator.connection && navigator.connection.type !== 3){ //not 2g
document.write('<link rel="stylesheet" href="hi-res-backgrounds.css" media="only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (-o-device-pixel-ratio:3/2),only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:1.5dppx)">');
}
Faced with developer apathy and little interest from vendors a new direction was sought, and an Editor’s Draft is now up at the W3C which looks more promising.
Like the old version it uses the navigator.connection
object but the type
attribute is gone. Instead we have the rather exciting bandwidth
and be-nice-to-your-users metered
attributes.
There is a third onchange
attribute which is a function that fires a change
(for when bandwidth changes), online
or offline
event.
Using navigator.connection.bandwidth
returns an integer value of the current bandwidth in megabytes per second. (Note how this is different to how ISPs report their bandwidth achievements in megabits per second.) It is to return infinity
if the bandwidth is unknown, and 0
if there is no connection.
The metered
attribute is a boolean that is true if the user is on something like a pre-pay or capped data plan. The spec suggests that the information necessary to know if metered
is true or false should come from the ISP, carrier or the user.
There are a couple of examples using the change
event in the draft spec: one to update navigator.connection.bandwidth
in the console as it changes, the other that uses it in conjunction with the metered
attribute to prevent automatic polling.
On to implementation. Unsurprisingly it’s even less widespread than type
. Mozilla have a prefixed version using mozConnection that’s in Firefox 12 and up, but I’m getting fairly useless results in Firefox 13 on Windows 7. On my home wifi the bandwidth is reported as Infinity, which according to the spec means it’s unknown. I can assure you the kids’ Buzz Lightyear toys are far closer to infinity than my home broadband will ever be.
WebKit also has a prefixed implementation webkitConnection
but it’s undefined in Canary and Chromium that I’ve tested.
Either way I’ve put up a demo using the Mozilla and WebKit prefixed versions (run in Firefox with the console open).
The fact that Mozilla and WebKit are off the mark already has them ahead of IE and Opera. It could well be in the next version of Chrome (don’t hold your breath for Safari) and I’m looking forward to making good use of it in production.
I’m glad the type
attribute isn’t being used any more — it’s likely to be misunderstood and misused. Misunderstood in that some devs may make assumptions about network speed based on the network type; misused in that some devs may make assumptions about users’ context.
Nevertheless it’s still going to be hard to use bandwidth
sensibly. Here are a few potential problems I can think of.
- There will be a lot of judgement calls to make e.g. where do we draw the line between fast and slow? Can you tell if your connection drops below 1MB/s? I know I would struggle with that.
- Even though we (probably) won’t be using type there is still room for baseless assumptions. For example a dev may decide that people with a connection below a particular level don’t need certain content.
- The point in time at which
bandwidth
is returned on a fluctuating network is very important and may be totally inappropriate for the majority of the session. - What would people think if they saw an interesting (but not essential) photo on a news site then returned to the story later to find the photo cropped or absent because the Network Information API was used to adjust image downloads over a slow connection?
There are probably many other issues that I haven’t thought of but I’m sure the benefits will outweigh them, and I’m looking forward to working out the best approaches and seeing what sort of consensus the community arrives at when the spec stabilizes.
Credits
- Jordan Moore for piquing my interest.
- Mathias Bynens for linking to obscure documents about WebKit that I would have gone the rest of my natural without ever knowing about.
- Robin Berjon for answering my questions on twitter.