The Network Information API is a HTML5 API for acquiring information about a device’s network connection. Despite not being a standard, it enjoys decent support across the main mobile browsers. It’s a pretty simple API to use, particularly in comparison with some of the HTML5 APIs we’ve looked at recently on this site (Service Workers, I’m looking at you!)
The Network Information API
So what can the Network Information API do anyway? The main things it can report are:
- What kind of network connection is available, e.g. cellular, WiFi, ethernet
- What the maximum download rate,
downlinkMax
, is, in Mbit/s - When the network type changes, e.g. if you switch from cell to WiFi
How to use the Network Information API
First, check if it’s supported by the current device:
1 2 3 |
if (navigator.connection) { //Network Information API is supported! } |
Detect the type of network connection
We can determine the type of connection like this:
1 2 |
var type = navigator.connection.type; console.log(type); |
The type of connection will be one of the following:
- cellular
- bluetooth
- ethernet
- wifi
- wimax
- other
- none
- mixed
- unknown
Detecting the downlinkMax property
Since this property is not widely supported (yet) even in browsers that implement the API, it’s best to check for it first:
1 2 3 4 |
if(navigator.connection.downlinkMax) { downMax = navigator.connection.downlinkMax; console.log(downMax); } |
Note that the value returned is determined by the properties of the underlying connection technology of the first network hop. As pointed out in the API draft, the end-to-end performance of any request cannot exceed this value, but it is also not a guarantee of performance and may be significantly worse.
Detecting change of connection type
The API exposes a change
event that fires whenever the connection type changes. We can use it like this:
1 2 3 |
navigator.connection.addEventListener('change' function (event) { console.log(connection.type); }); |
Using the API in practice
So now you know how to use the API, but what can you actually do with it?
Client side responsive design
One approach is to simply add a CSS class to the body
or some other tag of a page, based on whether the network connection was detected as being fast or slow. Then let the CSS rules determine whether to load larger, higher quality, or smaller, lower quality sized resources, or even omit some resources altogether.
For instance, you could use the following code to assign an appropriate class:
1 2 3 4 5 6 7 8 9 10 |
if(navigator.connection) { if((navigator.connection.downlinkMax && navigator.connection.downlinkMax>1) || navigator.connection.type=='wifi') { document.body.classList.add('hifi'); } else { document.body.classList.add('lofi'); } } } |
And then some simple CSS to specify which asset to use:
1 2 3 4 5 6 7 |
body.hifi #element { background: url(image-hi.jpg); } body.lofi #element { background: url(image-lo.jpg); } |
You could also change the class using the change event. If you do this, be careful not to replace a high quality asset with a lower quality one if the higher quality resource is already loaded!
The problem with this approach however, is that knowing the connection.type
doesn’t give you enough information to make a decision about what content to send to a device. More on this later.
Server side adaptation
This API also becomes very useful when combined with Service Workers. Paul Kinlan demonstrates how a service worker can be used in conjunction with the Network Information API to augment an HTTP request with extra headers that indicate the network connection type or speed.
A service worker is registered, which adds connection information to page requests, and the server can then send an appropriate response, with optimised content, images, video, or whatever else, for the detected network speed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
self.addEventListener("fetch", function(event) { var requestURL = new URL(event.request.url); var dm = 0; var navType = "unknown"; if(navigator.connection && navigator.connection.downlinkMax !== false) { dm = navigator.connection.downlinkMax; } if(navigator.connection && navigator.connection.type !== false) { navType = navigator.connection.type; } if (requestURL.origin == location.origin) { // append the MD header, set value to NetInfo's downlinkMax: // http://w3c.github.io/netinfo/#downlinkmax-attribute event.respondWith( fetch(event.request.url, { headers: { 'MD': dm, 'Network-Type': navType } }) ); } }); |
Controversy
There is some controversy around this API. Knowing the type of connection doesn’t really give you all the information you need to make a decision about what kind of content to send. A particular connection type does not guarantee a particular connection speed. So connection.type
is largely useless, unless you’re simply collecting statistics, because you really can’t make any useful decisions based on it. Airport/conference WiFi is almost always worse than cellular data as an example, and other|mixed|unknown
values don’t tell you anything. Attainable cellular data speed depends hugely on the number of people in each cell. Even if the connection truly is fast it counts for nothing if you have another app using up all of the bandwidth.
The downlinkMax
property offers something more usable, but only when considered as a best case scenario, which can be used to trigger some simple logic if this number exceeds some threshold.
It’s worth noting again, that the available connection speed can (and is likely to) change from second to second, because of network issues, other apps doing stuff in background.
The only way to make truly sensible and reliable decisions is to measure the true rate at which data is actually getting delivered to the browser, which is yet another useful job that a service worker could do!
Support
While the official W3C page for this API is dormant, work continues in the form of an Editor’s draft on the W3C’s github pages; although this does not in any way guarantee that an actual standard will ever be adopted, it does indicate that it is still being worked on. Indeed, at the time of writing, the Chrome for Mobile beta browser supports the downlinkMax
property, while Chrome stable does not yet; interest and activity around the API is thus alive and well.
The Network Information API is quite widely supported across most modern mobile browsers. Notable exceptions are iOS Safari, IE Mobile and Blackberry browsers. Will this change in the future? Microsoft has a pretty progressive attitude towards browser development these days, so it is certainly possible. iOS Safari is another story. With Apple dragging its feet with respect to browser developments (e.g. Service Workers, Pointer Events), so whether this one gets implemented is anyone’s guess. Of course, the API is still only an Editor’s draft, so that goes against it too.
Current support is illustrated below (reproduced from caniuse.com).
Android | iOS | IE Mobile | Opera Mobile | Opera Mini | Firefox Mobile | Chrome for Android | Blackberry | |
---|---|---|---|---|---|---|---|---|
Netinfo API | ||||||||
(Sources: caniuse.com, DeviceAtlas, mobilehtml5.org) |
Leave a Reply