Quantcast
Channel: Envato Tuts+ Code - Mobile Development
Viewing all articles
Browse latest Browse all 1836

HTML5: Network Information API

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-21598

Introduction

One of the most discussed concepts in the world of the web design is responsive web design. Thousands of articles have been written on responsive web design and I therefore won't discuss it in this article. However, responsive web design has an important limitation, responsive web design is for the most part based on the size of the browser's viewport.

While this approach works well for serving up images of the right size and resolution, it isn't ideal in all situations, video content being one example. What we really need in these cases is more information about the device's network connection.

Imagine you're visiting YouTube on your smartphone or tablet. You're at home and connected over Wi-Fi. In such cases, you don't care about the number of bytes that are being downloaded, you're only interested in high quality video content. This isn't true if you're connected over a slow mobile connection. In that case, you want to see the video, the quality is secondary.

I should be clear that every developer who wants a website to be really good still has to optimize the assets it serves to allow pages to load as fast as possible. However, in the above example, serving up a high resolution video isn't a waste of the user's bandwidth, but an improvement of the user experience.

The Network Information API is exactly what we need to find out more about the network connection of the device.

1. What is it?

The Network Information API provides access to the connection type the system is using to communicate with the network, cellular, Wi-Fi, Bluetooth, etc. It also provides a means for scripts to be notified if the connection type changes. This is to allow developers to make dynamic changes to the DOM and/or inform the user that the network connection type has changed.

The first release of the specification of the Network Information API was in 2001, but the API has changed several times since. As a proof of this, the current version is a mere editor's draft, which means that it's bound to change in the future.

Despite the changes, the use cases for this API are so interesting that it's really worth exploring it. In this article, we'll discuss the latest version of the specification, but we'll also look at some of the deprecated properties and events for reasons I'll explain later.

2. Implementation

The current version of the Network Information API exposes a connection object that belongs to the window.navigator object. The connection object contains one property, type, which returns the user agent's connection type. The type property can have one of the following values:

  • bluetooth
  • cellular
  • ethernet
  • none
  • wifi
  • other
  • unknown

Some of these values, such as bluetooth and wifi, are self-explanatory while others need a bit more explaining. The cellular type refers to a mobile connection, such as EDGE, 3G, 4G, etc. The other type means that the current connection type is not unknown, but it isn't any of the other types either. The unknown type means that the user agent has established a network connection, but it is unable to determine what the connection type is.

In addition to type, the Network Information API exposes the ontypechange event. It is fired every time the type of the network connection changes.

Developers can use the Network Information API to change some features based on the current connection type. For example, we can slow down a process that takes up significant bandwidth if we detect the device is using a mobile connection. The API also lets us assign a specific class to the html element, for example high-bandwidth, in the same way Modernizr does. We can leverage CSS to change one or more properties of an element, such as the background image.

Now that we know what the Network Information API does and who we can benefit form it, let's see which browsers support the API.

3. Browser Support

At the time of writing, the Network Information API is only supported by Firefox, using its vendor prefix, and Chrome Canary. In Chrome Canary, we have to enable the experimental web platform features flag to use the API. You can find more information in this post by Paul Irish.

As if support for the Network Information API wasn't already poor enough, Firefox up to version 30, the most recent version, supports the old API specification. Because of this and in case you want to play with the Network Information API right now, it's important to take a look at the properties and events exposed by the previous specification of the API.

The old specification exposed two properties, bandwidth and metered. The bandwidth property is a double representing an estimation of the current bandwidth in megabytes per second (MB/s). The metered property is a boolean that specifies if the the network connection of the device is subject to any limitations. The previous specification also defined a onchange event to notify any listeners about changes of the aforementioned properties.

To give you an idea of the new and the old version of the specification, in the next section we'll build a demo that uses both.

4. Demo

So far, we've covered the properties and the events exposed by the API as well as the API's use cases. In this section, we're going to create a simple web page to see the API in action.

The demo consists of an HTML5 page that has an unordered list with three list items. Each item contains a text snippet to verify the value of the properties exposed by the old and the new specification of the Network Information API. The list items are hidden by default and are only shown if the corresponding properties are supported.

The demo also detects if the browser implements the old specification of the API (to target Firefox) and if the browser supports the Network Information API at all. In the first case, you'll see the message Old API version supported, in the second case the message API not supported will be displayed.

Testing for support of the Network Information API is very simple as you can see below:

// Deal with vendor prefixes
var connection = window.navigator.connection    ||
                 window.navigator.mozConnection ||
                 null;
if (connection === null) {
   // API not supported :(
} else {
   // API supported! Let's start the fun :)
}

To detect if the version implemented is the old specification, we can test for the presence of the metered property as shown below:

if ('metered' in connection) {
   // Old version
} else {
   // New version
}

Once we've tested for support of the Network Information API and we've figured out which version of the specification the browser supports, we can attach a handler to the correct event. Inside the handler we update the text of the corresponding list item, for example type for the new API specification.

You can find the complete code of the demo below and you can also play with it if you like.

<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="author" content="Aurelio De Rosa"><title>Network Information API Demo by Aurelio De Rosa</title><style>
         *
         {
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
         }

         body
         {
            max-width: 500px;
            margin: 2em auto;
            padding: 0 0.5em;
            font-size: 20px;
         }

         h1
         {
            text-align: center;
         }

         .api-support
         {
            display: block;
         }

         .hidden
         {
            display: none;
         }

         .value
         {
            font-weight: bold;
         }

         .author
         {
            display: block;
            margin-top: 1em;
         }
      </style></head><body><h1>Network Information API</h1><span id="ni-unsupported" class="api-support hidden">API not supported</span><span id="nio-supported" class="api-support hidden">Old API version supported</span><ul><li class="new-api hidden">
            The connection type is <span id="t-value" class="value">undefined</span>.</li><li class="old-api hidden">
            The connection bandwidth is <span id="b-value" class="value">undefined</span>.</li><li class="old-api hidden">
            The connection is <span id="m-value" class="value">undefined</span>.</li></ul><small class="author">
         Demo created by <a href="http://www.audero.it">Aurelio De Rosa</a>
         (<a href="https://twitter.com/AurelioDeRosa">@AurelioDeRosa</a>).<br />
         This demo is part of the <a href="https://github.com/AurelioDeRosa/HTML5-API-demos">HTML5 API demos repository</a>.</small><script>
         var connection = window.navigator.connection    ||
                          window.navigator.mozConnection ||
                          null;
         if (connection === null) {
            document.getElementById('ni-unsupported').classList.remove('hidden');
         } else if ('metered' in connection) {
            document.getElementById('nio-supported').classList.remove('hidden');
            [].slice.call(document.getElementsByClassName('old-api')).forEach(function(element) {
               element.classList.remove('hidden');
            });

            var bandwidthValue = document.getElementById('b-value');
            var meteredValue = document.getElementById('m-value');

            connection.addEventListener('change', function (event) {
               bandwidthValue.innerHTML = connection.bandwidth;
               meteredValue.innerHTML = (connection.metered ? '' : 'not ') + 'metered';
            });
            connection.dispatchEvent(new Event('change'));
         } else {
            var typeValue = document.getElementById('t-value');
            [].slice.call(document.getElementsByClassName('new-api')).forEach(function(element) {
               element.classList.remove('hidden');
            });

            connection.addEventListener('typechange', function (event) {
               typeValue.innerHTML = connection.type;
            });
            connection.dispatchEvent(new Event('typechange'));
         }
</script></body></html>

Conclusion

In this article, I introduced you to the Network Information API. In the first part of this article, we've discussed what the API is and what it can do for us. We also learned what properties and events the Network Information API exposes. As I mentioned in Browser Support, the API is currently poorly supported, but this is in part due to several changes of the API's specification.

The Network Information API is very simple to use and there are no excuses to not take advantage of the information it offers once it's supported by more browsers. What do you think of this API? Will you use it when it's supported by more browsers?

2014-08-08T16:45:05.000Z2014-08-08T16:45:05.000ZAurelio De Rosa

Viewing all articles
Browse latest Browse all 1836

Trending Articles