In this codelab, you'll learn how to adapt your content based on the network quality. This page's background video will load only when users are on a fast network. On slower networks, an image will load instead.
The
Network Information API
enables you to access information about the user's connection quality. You will
use its effectiveType
property to decide when to serve a video and when to
serve an image. effectiveType
can be 'slow-2g'
, '2g'
, '3g'
, or '4g'
.
Step 1: Check connection type
The index.html
file contains a <video>
tag to display the background video (line 22). The code in script.js
loads the video by setting the video tag's src
attribute. (The video loading code is described in more detail in Step 2.)
To load the video conditionally, first check if the Network Information API is available; if it is, check the connection type.
- In
script.js
, add anif
statement that tests whether thenavigator.connection
object exists and whether it has theeffectiveType
property. - Add an
if
statement to check theeffectiveType
of the network.
if (navigator.connection && !!navigator.connection.effectiveType) {
if (navigator.connection.effectiveType === '4g') {
// Only load video on the fastest connections.
} else {
// In any other case load the image.
}
}
Wrap the existing video loading code in an else
statement, so that video will
still load in browsers that don't support the Network Information API.
if (navigator.connection && !!navigator.connection.effectiveType) {
if (navigator.connection.effectiveType === '4g') {
// video loading code
} else {
// image loading code
}
} else {
const video = document.getElementById('coverVideo');
const videoSource = video.getAttribute('data-src');
video.setAttribute('src', videoSource);
video.setAttribute('style', 'height: 100%; width: 100%; display:inline');
}
Step 2: Load video
If the effectiveType
is '4g'
, use the video loading code from the
beginning of the codelab.
if (navigator.connection.effectiveType === '4g') {
const video = document.getElementById('coverVideo');
const videoSource = video.getAttribute('data-src');
video.setAttribute('src', videoSource);
video.setAttribute('style', 'height: 100%; width: 100%; display:inline');
} else {
// image loading code
}
Here's how the video loading code works: the <video>
tag doesn't download or display anything at first because its src
attribute is not set. The video URL to load is specified using the data-src
attribute.
<video id="coverVideo" playsinline autoplay loop muted data-src="https://cdn.glitch.com/b6491350-b058-4eb6-aa6c-55c93122073e%2FMatrix%2C%20Console%2C%20Hacking%2C%20Code.mp4?1551464245607"></video>
Data attributes allow you to store extra information on standard HTML elements. A data element can be named anything, as long as it starts with "data-".
To actually display the video on the page, you need to get the value from data-src
and set it as the video element's src
attribute.
First, get the DOM element that contains the asset:
const video = document.getElementById('coverVideo');
Then get the resource location from the data-src
attribute:
const videoSource = video.getAttribute('data-src');
And finally set that as the src
attribute of the video element:
video.setAttribute('src', videoSource);
The last line takes care of CSS positioning:
video.setAttribute('style', 'height: 100%; width: 100%; display:inline');
Step 3: Load image
To conditionally load an image on slower networks, use the same strategy as for the video.
Add an image element to index.html
(right after the video element), and use
the data-src
attribute instead of the src
attribute.
<img id="coverImage" data-src="https://cdn.glitch.com/36529535-5976-40f8-979b-40c898b86bd0%2F36529535-5976-40f8-979b-40c898b86bd0_1_Sn80dgiwpMjBVrqjfiDbnA.jpg?1553003835358" />
In script.js
, add code to set the image's src
attribute depending on the
effectiveType
of the network.
if (navigator.connection.effectiveType === '4g') {
const video = document.getElementById('coverVideo');
const videoSource = video.getAttribute('data-src');
video.setAttribute('src', videoSource);
video.setAttribute('style', 'height: 100%; width: 100%; display:inline');
} else {
const image = document.getElementById('coverImage');
const imageSource = image.getAttribute('data-src');
image.setAttribute('src', imageSource);
image.setAttribute('style', 'height: 100%; width: 100%; display:inline');
}
Try it out
To test it yourself:
- To preview the site, press View App. Then press Fullscreen .
- Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
- Click the Network tab.
- Click the Throttling drop-down, which is set to No throttling by default. Select Fast 3G.
Now reload the page with Fast 3G still enabled. The app loads an image in the background instead of the video:
Extra Credit: Respond to changes
Remember how this API has an onchange
event listener?
You can use it for many things: dynamically adapting content such as video quality; restarting deferred data transfers when a change to a high-bandwidth network type is detected; or notifying users when the network quality changes.
Here's a simple example of how to use this listener. Add it to script.js
. This
code will call the displayNetworkInfo
function whenever the network
information changes.
navigator.connection.addEventListener('change', displayNetworkInfo);
There's already an empty <h2>
element on the index.html
page. Now define the
displayNetworkInfo
function so that it displays the network information in the
<h2>
element and invoke the function.
function displayNetworkInfo() {
document.getElementById('connection').innerHTML = navigator.connection.effectiveType;
}
displayNetworkInfo();
Here's the final state of the app on Glitch.
To test it again:
- To preview the site, press View App. Then press Fullscreen .
- Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
- Click the Network tab.
- Click the Throttling drop-down, which is set to No throttling by default. Select Fast 3G.
- Reload the app.
The app will update the network information to 3g: