Adaptive Serving using JavaScript and the Network Information API
Addy Osmani
Posted on October 8, 2018
navigator.connection.effectiveType
is useful for delivering different assets based on the quality of the user's network connection.
effectiveType is a property of the Network Information API, exposed to JavaScript via the navigator.connection object. In Chrome, you can drop the following into DevTools to see your effective connection type (ECT):
console.log(navigator.connection.effectiveType); // 4G
Possible values for effectiveType
are 'slow-2g', '2g', '3g', or '4g'. On slow connections this capability allows you to improve how quickly pages load by serving lower-quality versions of resources.
Before Chrome 62, we only exposed the theoretical network connection type to developers (via navigator.connection.type
) rather than the network quality actually experienced by the client.
Chrome's implementation of effective connection type is now determined using a combination of recently observed round-trip times (rtt) and downlink values.
It summarizes measured network performance as the cellular connection type (e.g. 2G) most similar, even if the actual connection is WiFi. i.e. picture you're on Starbucks WiFi, but your actual effective network type is 2G or 3G.
What about responding to changes in network quality? We can use the connection.onchange
event listener to monitor for connection changes:
function onConnectionChange() {
const { rtt, downlink, effectiveType, saveData } = navigator.connection;
console.log(`Effective network connection type: ${effectiveType}`);
console.log(`Downlink Speed/bandwidth estimate: ${downlink}Mb/s`);
console.log(`Round-trip time estimate: ${rtt}ms`);
console.log(`Data-saver mode on/requested: ${saveData}`);
}
navigator.connection.addEventListener('change', onConnectionChange)
Below is a quick test where I emulated a "Low-end mobile" profile in DevTools and was able to switch from "4g" to "2g" conditions:
effectiveType
is supported in Chrome, Opera and Firefox on Android. A number of other network quality hints are available on navigator.connection
, including rtt
, downlink
and downlinkMax
.
An open-source project I've used effectiveType
in was a Vue.js Google Doodles app. Using data-binding, we were able to set a connection
property to either fast
or slow
based on ECT values. Roughly:
if (/\slow-2g|2g|3g/.test(navigator.connection.effectiveType)) {
this.connection = "slow";
} else {
this.connection = "fast";
}
This allowed us to conditionally render different output (a video vs. a low-res image) depending on the user's effective connection type.
<template>
<div id="home">
<div v-if="connection === 'fast'">
<!-- 1.3MB video -->
<video class="theatre" autoplay muted playsinline control>
<source src="/static/img/doodle-theatre.webm" type="video/webm">
<source src="/static/img/doodle-theatre.mp4" type="video/mp4">
</video>
</div>
<!-- 28KB image -->
<div v-if="connection === 'slow'">
<img class="theatre" src="/static/img/doodle-theatre-poster.jpg">
</div>
</div>
</template>
Max Böck wrote an interesting article about network-aware components using React. He similarly highlighted how to render different components based on the network speed:
switch(connectionType) {
case '4g':
return <Video src={videoSrc} />
case '3g':
return <Image src={imageSrc.hires} alt={alt} />
default:
return <Image src={imageSrc.lowres} alt={alt} />
}
Note: You can pair effectiveType
with Service Workers to adapt to when users are offline in addition to slower effective connection types.
For debugging, you can override the network quality estimate using the Chrome flag "force-effective-connection-type" which can be set from chrome://flags. DevTools Network emulation can provide a limited debugging experience for ECT too.
effectiveType
values are also exposed via Client Hints allowing developers to convey Chrome's network connection speed to servers.
Further reading on this feature, see:
- Google Chrome Network Information API Sample
- Connection-aware components
- Dynamic resources using the NetInfo API and service workers
- Network-based image loading
- Chrome 62 Beta: Network Quality Estimator API
- Intent to Ship: NetInfo API extension for network quality
You can also find this post on addyosmani.com
Posted on October 8, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.