The Network Information API provides an interface for web applications to access the underlying connection information of the device.

The functionality described in this specification was initially specified as part of the System Information API but has been extracted in order to be more readily available, more straightforward to implement, and in order to produce a specification that could be implemented on its own merits without interference with other, often unrelated, features.

Introduction

The Network Information API provides an interface enabling web applications to access the underlying connection information of the device.

Use Cases

The main use case of the Network Information API is to allow applications to be gentle with the user's bandwidth when they know it is rare or expensive. Even if there are not many applications that do this currently, this specification offers the the tools needed to enable this, allowing it to become more common.

A few hypothetical examples would be:

Outstanding issues

The specification currently requests the user agent to expose two properties: bandwidth and metered. The working group currently does not have consensus on these.

One concern is that bandwidth may be hard to implement, can be quite power-consuming to keep up-to-date and its value might be unrelated to the actual connection quality that could be affected by the server.
A solution to fix this would be to return non absolute values that couldn't be easily abused and would be more simple to produce for the user agent. For example, having a set of values like very-slow, slow, fast and very-fast. Another solution would be to have only values like very-slow, slow and the empty string."

metered may also be hard to implement as there is currently no standard way for the OS to know if the current connection is metered. The approach of the specification is to leave the implementation details to the user agent. That way, the attribute could return a value based on a heuristic, on knowledge of the current connection status or even by directly asking the user for the information.
It is interesting to point that Android 4.1 and Windows 8 both have a way to check if the current connection is metered. Android is using a boolean (isActiveNetworkMetered()) while Windows 8 allow the developer to ask for different information (NetworkCostType, ApproachingDataLimit, OverDataLimit, Roaming).

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to expose the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]].

Terminology

The EventHandler interface represents a callback used for event handlers as defined in [[!HTML5]].

The concepts queue a task and fire a simple event are defined in [[!HTML5]].

The terms event handlers and event handler event types are defined in [[!HTML5]].

The concepts of browsing context and active document are defined in [[!HTML5]].

The concept of document domain is defined in [[!HTML5]].

Security and privacy considerations

The API defined in this specification is used to determine the connection information of the hosting device. The information disclosed has minimal impact on privacy or fingerprinting, and therefore is exposed without permission grants. For example, authors cannot directly know what kind of connection is currently in use by the hosting device.

The NetworkInformation interface

The NetworkInformation interface is exposed on the Navigator object.

readonly attribute Connection connection
The object from which connection information is accessed.

The Connection interface

The Connection interface provides a handle to the device's connection information.

readonly attribute double bandwidth
The user agent MUST set the value of the bandwidth attribute to:
  • 0 if the user is currently offline;
  • Infinity if the bandwidth is unknown;
  • an estimation of the current bandwidth in MB/s (Megabytes per seconds) available for communication with the browsing context active document's domain.
readonly attribute boolean metered

A connection is metered when the user's connection is subject to a limitation from his Internet Service Provider strong enough to request web applications to be careful with the bandwidth usage.

What is a metered connection is voluntarily left to the user agent to judge. It would not be possible to give an exhaustive list of limitations considered strong enough to flag the connection as metered and even if doable, some limitations can be considered strong or weak depending on the context.
Examples of metered connections are mobile connections with a small bandwidth quota or connections with a pay-per use plan.

The user agent MUST set the value of the metered attribute to true if the connection with the browsing context active document's domain is metered and false otherwise. If the implementation is not able to know the status of the connection or if the user is offline, the value MUST be set to false.

If unable to know if a connection is metered, a user agent could ask the user about the status of his current connection. For example, a preference could let the user define if the mobile connection used on the device is metered.
[TreatNonCallableAsNull] attribute EventHandler onchange

When the Connection changes, the user agent MUST queue a task which updates the Connection properties and fire a simple event named change at the Connection object.

When the user goes online or offline, in addition to the change event fired on the Connection object, the user agent has to fire a simple event named either online or offline depending on the applicable value, as defined in [[!HTML5]].

Event handlers

The following are the event handlers (and their corresponding event handler event types) that MUST be supported as attributes by the Connection object:

event handler event handler event type
onchange change

Examples

This trivial example writes the connection bandwidth to the console and shows it again each time it is changing:

        function show() {
          console.log(navigator.connection.bandwidth);
        }

        navigator.connection.addEventListener('change', show, false);

        show();
      

This example shows how an image viewer can select a low definition or a high definition image based on the current connection bandwidth:

        <!DOCTYPE>
        <html>
          <head>
            <title>Pony viewer</title>
          </head>
          <body>
            <img id='pony' alt="An image showing a pony" title="My precious!">
            <script>
              var i = document.getElementById('pony');

              if (navigator.connection.bandwidth > 2) {
                i.src = "http://example.com/pony_hd.png";
              } else {
                i.src = "http://example.com/pony_ld.png";
              }
            </script>
          </body>
        </html>
      

This example shows how an application can prevent automatic polling using the metered attribute:

        <!DOCTYPE html>
        <html>
          <head>
            <title>Conditional polling</title>
            <script>
              var gPreviousMetered = navigator.connection.metered;
              var gIntervalId;

              function poll() {
                // poll stuff
              }

              navigator.connection.addEventListener('change', function() {
                if (gPreviousMetered == navigator.connection.metered) {
                  return;
                }

                gPreviousMetered = navigator.connection.metered;
                if (!navigator.connection.metered) {
                  gIntervalId = setInterval(poll, 1000);
                } else {
                  clearInterval(gIntervalId);
                }
              }, false);

              // At load time.
              if (!navigator.connection.metered) {
                gIntervalId = setInterval(poll, 1000);
              }
            </script>
          </head>
          <body>
            <button onclick="poll();">Poll</button>
          </body>
        </html>
      

Acknowledgments

Thanks to Robin Berjon, Frederick Hirsch and Jonas Sicking for their help.