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.
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.
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.
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.
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>
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?
Create Modern Vue Apps Using Create-Vue and Vite
/Pros and Cons of Using WordPress
/How to Fix the “There Has Been a Critical Error in Your Website” Error in WordPress
/How To Fix The “There Has Been A Critical Error in Your Website” Error in WordPress
/How to Create a Privacy Policy Page in WordPress
/How Long Does It Take to Learn JavaScript?
/The Best Way to Deep Copy an Object in JavaScript
/Adding and Removing Elements From Arrays in JavaScript
/Create a JavaScript AJAX Post Request: With and Without jQuery
/5 Real-Life Uses for the JavaScript reduce() Method
/How to Enable or Disable a Button With JavaScript: jQuery vs. Vanilla
/How to Enable or Disable a Button With JavaScript: jQuery vs Vanilla
/Confirm Yes or No With JavaScript
/How to Change the URL in JavaScript: Redirecting
/15+ Best WordPress Twitter Widgets
/27 Best Tab and Accordion Widget Plugins for WordPress (Free & Premium)
/21 Best Tab and Accordion Widget Plugins for WordPress (Free & Premium)
/30 HTML Best Practices for Beginners
/31 Best WordPress Calendar Plugins and Widgets (With 5 Free Plugins)
/25 Ridiculously Impressive HTML5 Canvas Experiments
/How to Implement Email Verification for New Members
/How to Create a Simple Web-Based Chat Application
/30 Popular WordPress User Interface Elements
/Top 18 Best Practices for Writing Super Readable Code
/Best Affiliate WooCommerce Plugins Compared
/18 Best WordPress Star Rating Plugins
/10+ Best WordPress Twitter Widgets
/20+ Best WordPress Booking and Reservation Plugins
/Working With Tables in React: Part Two
/Best CSS Animations and Effects on CodeCanyon
/30 CSS Best Practices for Beginners
/How to Create a Custom WordPress Plugin From Scratch
/10 Best Responsive HTML5 Sliders for Images and Text… and 3 Free Options
/16 Best Tab and Accordion Widget Plugins for WordPress
/18 Best WordPress Membership Plugins and 5 Free Plugins
/25 Best WooCommerce Plugins for Products, Pricing, Payments and More
/10 Best WordPress Twitter Widgets
1 /12 Best Contact Form PHP Scripts for 2020
/20 Popular WordPress User Interface Elements
/10 Best WordPress Star Rating Plugins
/12 Best CSS Animations on CodeCanyon
/12 Best WordPress Booking and Reservation Plugins
/12 Elegant CSS Pricing Tables for Your Latest Web Project
/24 Best WordPress Form Plugins for 2020
/14 Best PHP Event Calendar and Booking Scripts
/Create a Blog for Each Category or Department in Your WooCommerce Store
/8 Best WordPress Booking and Reservation Plugins
/Best Exit Popups for WordPress Compared
/Best Exit Popups for WordPress Compared
/11 Best Tab & Accordion WordPress Widgets & Plugins
/12 Best Tab & Accordion WordPress Widgets & Plugins
1 /New Course: Practical React Fundamentals
/Preview Our New Course on Angular Material
/Build Your Own CAPTCHA and Contact Form in PHP
/Object-Oriented PHP With Classes and Objects
/Best Practices for ARIA Implementation
/Accessible Apps: Barriers to Access and Getting Started With Accessibility
/Dramatically Speed Up Your React Front-End App Using Lazy Loading
/15 Best Modern JavaScript Admin Templates for React, Angular, and Vue.js
/15 Best Modern JavaScript Admin Templates for React, Angular and Vue.js
/19 Best JavaScript Admin Templates for React, Angular, and Vue.js
/New Course: Build an App With JavaScript and the MEAN Stack
/Hands-on With ARIA: Accessibility Recipes for Web Apps
/10 Best WordPress Facebook Widgets
13 /Hands-on With ARIA: Accessibility for eCommerce
/New eBooks Available for Subscribers
/Hands-on With ARIA: Homepage Elements and Standard Navigation
/Site Accessibility: Getting Started With ARIA
/How Secure Are Your JavaScript Open-Source Dependencies?
/New Course: Secure Your WordPress Site With SSL
/Testing Components in React Using Jest and Enzyme
/Testing Components in React Using Jest: The Basics
/15 Best PHP Event Calendar and Booking Scripts
/Create Interactive Gradient Animations Using Granim.js
/How to Build Complex, Large-Scale Vue.js Apps With Vuex
1 /Examples of Dependency Injection in PHP With Symfony Components
/Set Up Routing in PHP Applications Using the Symfony Routing Component
1 /A Beginner’s Guide to Regular Expressions in JavaScript
/Introduction to Popmotion: Custom Animation Scrubber
/Introduction to Popmotion: Pointers and Physics
/New Course: Connect to a Database With Laravel’s Eloquent ORM
/How to Create a Custom Settings Panel in WooCommerce
/Building the DOM faster: speculative parsing, async, defer and preload
1 /20 Useful PHP Scripts Available on CodeCanyon
3 /How to Find and Fix Poor Page Load Times With Raygun
/Introduction to the Stimulus Framework
/Single-Page React Applications With the React-Router and React-Transition-Group Modules
12 Best Contact Form PHP Scripts
1 /Getting Started With the Mojs Animation Library: The ShapeSwirl and Stagger Modules
/Getting Started With the Mojs Animation Library: The Shape Module
/Getting Started With the Mojs Animation Library: The HTML Module
/Project Management Considerations for Your WordPress Project
/8 Things That Make Jest the Best React Testing Framework
/Creating an Image Editor Using CamanJS: Layers, Blend Modes, and Events
/New Short Course: Code a Front-End App With GraphQL and React
/Creating an Image Editor Using CamanJS: Applying Basic Filters
/Creating an Image Editor Using CamanJS: Creating Custom Filters and Blend Modes
/Modern Web Scraping With BeautifulSoup and Selenium
/Challenge: Create a To-Do List in React
1 /Deploy PHP Web Applications Using Laravel Forge
/Getting Started With the Mojs Animation Library: The Burst Module
/10 Things Men Can Do to Support Women in Tech
/A Gentle Introduction to Higher-Order Components in React: Best Practices
/Challenge: Build a React Component
/A Gentle Introduction to HOC in React: Learn by Example
/A Gentle Introduction to Higher-Order Components in React
/Creating Pretty Popup Messages Using SweetAlert2
/Creating Stylish and Responsive Progress Bars Using ProgressBar.js
/How to Make a Real-Time Sports Application Using Node.js
/Creating a Blogging App Using Angular & MongoDB: Delete Post
/Set Up an OAuth2 Server Using Passport in Laravel
/Creating a Blogging App Using Angular & MongoDB: Edit Post
/Creating a Blogging App Using Angular & MongoDB: Add Post
/Introduction to Mocking in Python
/Creating a Blogging App Using Angular & MongoDB: Show Post
/Creating a Blogging App Using Angular & MongoDB: Home
/Creating a Blogging App Using Angular & MongoDB: Login
/Creating Your First Angular App: Implement Routing
/Persisted WordPress Admin Notices: Part 4
/Creating Your First Angular App: Components, Part 2
/Persisted WordPress Admin Notices: Part 3
/Creating Your First Angular App: Components, Part 1
/How Laravel Broadcasting Works
/Persisted WordPress Admin Notices: Part 2
/Create Your First Angular App: Storing and Accessing Data
/Persisted WordPress Admin Notices: Part 1
/Error and Performance Monitoring for Web & Mobile Apps Using Raygun
/Using Luxon for Date and Time in JavaScript
7 /How to Create an Audio Oscillator With the Web Audio API
/How to Cache Using Redis in Django Applications
/20 Essential WordPress Utilities to Manage Your Site
/Beginner’s Guide to Angular 4: HTTP
/Rapid Web Deployment for Laravel With GitHub, Linode, and RunCloud.io
/Beginners Guide to Angular 4: Routing
/Beginner’s Guide to Angular 4: Services
/Beginner’s Guide to Angular 4: Components
/Creating a Drop-Down Menu for Mobile Pages
/Introduction to Forms in Angular 4: Writing Custom Form Validators
/10 Best WordPress Booking & Reservation Plugins
/Getting Started With Redux: Connecting Redux With React
/Getting Started With Redux: Learn by Example
/Getting Started With Redux: Why Redux?
/Understanding Recursion With JavaScript
/How to Auto Update WordPress Salts
/How to Download Files in Python
/Eloquent Mutators and Accessors in Laravel
1 /10 Best HTML5 Sliders for Images and Text
/Site Authentication in Node.js: User Signup
/Creating a Task Manager App Using Ionic: Part 2
/Creating a Task Manager App Using Ionic: Part 1
/Introduction to Forms in Angular 4: Reactive Forms
/Introduction to Forms in Angular 4: Template-Driven Forms
/24 Essential WordPress Utilities to Manage Your Site
/25 Essential WordPress Utilities to Manage Your Site
/Get Rid of Bugs Quickly Using BugReplay
1 /Manipulating HTML5 Canvas Using Konva: Part 1, Getting Started
/10 Must-See Easy Digital Downloads Extensions for Your WordPress Site
/22 Best WordPress Booking and Reservation Plugins
/Understanding ExpressJS Routing
/15 Best WordPress Star Rating Plugins
/Creating Your First Angular App: Basics
/Inheritance and Extending Objects With JavaScript
/Introduction to the CSS Grid Layout With Examples
1Performant Animations Using KUTE.js: Part 5, Easing Functions and Attributes
Performant Animations Using KUTE.js: Part 4, Animating Text
/Performant Animations Using KUTE.js: Part 3, Animating SVG
/New Course: Code a Quiz App With Vue.js
/Performant Animations Using KUTE.js: Part 2, Animating CSS Properties
Performant Animations Using KUTE.js: Part 1, Getting Started
/10 Best Responsive HTML5 Sliders for Images and Text (Plus 3 Free Options)
/Single-Page Applications With ngRoute and ngAnimate in AngularJS
/Deferring Tasks in Laravel Using Queues
/Site Authentication in Node.js: User Signup and Login
/Working With Tables in React, Part Two
/Working With Tables in React, Part One
/How to Set Up a Scalable, E-Commerce-Ready WordPress Site Using ClusterCS
/New Course on WordPress Conditional Tags
/TypeScript for Beginners, Part 5: Generics
/Building With Vue.js 2 and Firebase
6 /Best Unique Bootstrap JavaScript Plugins
/Essential JavaScript Libraries and Frameworks You Should Know About
/Vue.js Crash Course: Create a Simple Blog Using Vue.js
/Build a React App With a Laravel RESTful Back End: Part 1, Laravel 5.5 API
/API Authentication With Node.js
/Beginner’s Guide to Angular: Routing
/Beginners Guide to Angular: Routing
/Beginner’s Guide to Angular: Services
/Beginner’s Guide to Angular: Components
/How to Create a Custom Authentication Guard in Laravel
/Learn Computer Science With JavaScript: Part 3, Loops
/Build Web Applications Using Node.js
/Learn Computer Science With JavaScript: Part 4, Functions
/Learn Computer Science With JavaScript: Part 2, Conditionals
/Create Interactive Charts Using Plotly.js, Part 5: Pie and Gauge Charts
/Create Interactive Charts Using Plotly.js, Part 4: Bubble and Dot Charts
Create Interactive Charts Using Plotly.js, Part 3: Bar Charts
/Awesome JavaScript Libraries and Frameworks You Should Know About
/Create Interactive Charts Using Plotly.js, Part 2: Line Charts
/Bulk Import a CSV File Into MongoDB Using Mongoose With Node.js
/Build a To-Do API With Node, Express, and MongoDB
/Getting Started With End-to-End Testing in Angular Using Protractor
/TypeScript for Beginners, Part 4: Classes
/Object-Oriented Programming With JavaScript
/10 Best Affiliate WooCommerce Plugins Compared
/Stateful vs. Stateless Functional Components in React
/Make Your JavaScript Code Robust With Flow
/Build a To-Do API With Node and Restify
/Testing Components in Angular Using Jasmine: Part 2, Services
/Testing Components in Angular Using Jasmine: Part 1
/Creating a Blogging App Using React, Part 6: Tags
/React Crash Course for Beginners, Part 3
/React Crash Course for Beginners, Part 2
/React Crash Course for Beginners, Part 1
/Set Up a React Environment, Part 4
1 /Set Up a React Environment, Part 3
/New Course: Get Started With Phoenix
/Set Up a React Environment, Part 2
/Set Up a React Environment, Part 1
/Command Line Basics and Useful Tricks With the Terminal
/How to Create a Real-Time Feed Using Phoenix and React
/Build a React App With a Laravel Back End: Part 2, React
/Build a React App With a Laravel RESTful Back End: Part 1, Laravel 9 API
/Creating a Blogging App Using React, Part 5: Profile Page
/Pagination in CodeIgniter: The Complete Guide
/JavaScript-Based Animations Using Anime.js, Part 4: Callbacks, Easings, and SVG
/JavaScript-Based Animations Using Anime.js, Part 3: Values, Timeline, and Playback
/Learn to Code With JavaScript: Part 1, The Basics
/10 Elegant CSS Pricing Tables for Your Latest Web Project
/Getting Started With the Flux Architecture in React
/Getting Started With Matter.js: The Composites and Composite Modules
Getting Started With Matter.js: The Engine and World Modules
/10 More Popular HTML5 Projects for You to Use and Study
/Understand the Basics of Laravel Middleware
/Iterating Fast With Django & Heroku
/Creating a Blogging App Using React, Part 4: Update & Delete Posts
/Creating a jQuery Plugin for Long Shadow Design
/How to Register & Use Laravel Service Providers
2 /Unit Testing in React: Shallow vs. Static Testing
/Creating a Blogging App Using React, Part 3: Add & Display Post
/Creating a Blogging App Using React, Part 2: User Sign-Up
20 /Creating a Blogging App Using React, Part 1: User Sign-In
/Creating a Grocery List Manager Using Angular, Part 2: Managing Items
/9 Elegant CSS Pricing Tables for Your Latest Web Project
/Angular vs. React: 7 Key Features Compared
/Creating a Grocery List Manager Using Angular, Part 1: Add & Display Items
New eBooks Available for Subscribers in June 2017
/Create Interactive Charts Using Plotly.js, Part 1: Getting Started
/The 5 Best IDEs for WordPress Development (And Why)
/33 Popular WordPress User Interface Elements
/New Course: How to Hack Your Own App
/How to Install Yii on Windows or a Mac
/What Is a JavaScript Operator?
/How to Register and Use Laravel Service Providers
/
waly Good blog post. I absolutely love this…