Adapt video to image serving based on network quality

Milica Mihajlija
Milica Mihajlija

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'.

Browser Support

  • Chrome: 61.
  • Edge: 79.
  • Firefox: not supported.
  • Safari: not supported.

Source

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.

  1. In script.js, add an if statement that tests whether the navigator.connection object exists and whether it has the effectiveType property.
  2. Add an if statement to check the effectiveType 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:

  1. To preview the site, press View App. Then press Fullscreen fullscreen.
  2. Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
  3. Click the Network tab.
  4. Click the Throttling drop-down, which is set to No throttling by default. Select Fast 3G.

DevTools Network tab with Fast 3G throttling option highlighted

Now reload the page with Fast 3G still enabled. The app loads an image in the background instead of the video:

Matrix-like image background with 'NETWORK INFORMATION' text overlay

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.

Matrix-like video background with 'NETWORK INFORMATION 4g' text overlay

To test it again:

  1. To preview the site, press View App. Then press Fullscreen fullscreen.
  2. Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.
  3. Click the Network tab.
  4. Click the Throttling drop-down, which is set to No throttling by default. Select Fast 3G.
  5. Reload the app.

The app will update the network information to 3g:

Matrix-like video background with 'NETWORK INFORMATION 3g' text overlay