Dev Tips: Only download JavaScript when it is appropriate

Dev Tips


Hey everyone! I have a different sort of tip for you today, hope it's useful.
 

JavaScript: Conditional JavaScript, only download when it is appropriate


Intro

In this post, I'd like to share a few techniques which you can use for selectively downloading/executing resources such as JavaScript.

As an example, if the users device does not have a lot a RAM, you could decide to skip the downloading (and in turn, the parse + execution costs) of a particular JavaScript resource.

Note: I won't be specifying the exact times you should minimise usage of JavaScript. It ultimately depends on your use case.

  • If I were building a game in WebGL, I'd probably load files regardless of navigator.deviceMemory.
  • If I were building Wikipedia, I might indeed skip loading of some JavaScript based on navigator.deviceMemory + navigator.getBattery() + navigator.connection.downlink.


Load JavaScript if the device has enough RAM

Let's start out with this:

if (navigator.deviceMemory > 1) {
    await import('./costly-module.js');
}
Getting the device memory from JavaScript

Browser support is limited to Chromium based browsers, which according to caniuse is 70% of the global usage stats. If navigator.deviceMemory is undefined, maybe consider loading the JavaScript regardless.

Detecting device memory on the server

The Web Platform is full of hidden features. Turns out you can get this information on your server!

Getting the device memory from a network request header

The browser can send a network request header which means your server can decide on the most appropriate resource to send back down. Use this <meta> tag in your HTML to activate this feature:

<meta http-equiv="Accept-CH" content="Device-Memory">


Load JavaScript when the device has enough CPU

You can get the number of logical processors on the users device with hardwareConcurrency.

if (navigator.hardwareConcurrency > 4) {
    await import('./costly-module.js');
}

MDN has an explanation:

 

The number of logical processor cores can be used to measure the number of threads which can effectively be run at once without them having to context switch.

Logical processors

This feature can be especially useful when creating new Workers - part of the Web Workers API.

Browser support is very good.


Load JavaScript when the user has enough battery left

We've all been there. Low battery 🔋️, no charger, and you start clearing apps in the hope that your 4% lasts on the journey home.

A page with JavaScript will utilise more battery than a page without JavaScript - and yes, the same applies to CSS and images.

The Network Download, Parse and Execution costs will defintely use battery, but don't forget the variety of tasks which JavaScript is capable of e.g. creating long-running timers.

// { level: 0.53 (53%), charging: true...}
const {level, charging} = await navigator.getBattery();

// If the device is currently charging
// Or the battery level is more than 20%
if (charging || level > 0.2) {
        await import('./costly-module.js');
}

You also get charging times and discharging times which in some scenarios could be even more valuable than what the current level is.

Battery Status

Browser support seems to be limited to Chromium based browsers. Interestingly it was removed in Firefox due to privacy concerns (a.k.a. fingerprinting 🖐🏼️).


Load JavaScript when the device has enough storage

This one really depends on what the JavaScript is doing. For example if the JavaScript is:

  • Downloading lots of maps as part of a game.
  • Downloading + Saving website resources via a Service Worker (e.g. for offline capabilities).
  • Downloading large textures/assets part of a visualisation.

Then maybe consider the idea of using storage availability to influence downloading of resources.

const {quota} = await navigator.storage.estimate();
const fiftyMegabytesInBytes = 50 * 1e+6;

if (quota > fiftyMegabytesInBytes) {
    await import('./costly-module.js');
}

Browser support is decent

Storage quota


Load JavaScript when the device has a good network connection

At this point, you can argue it's also effective to skip the download of any optional resource - not just JavaScript.

// ⚠️ 4g does not mean fast!
if (navigator.connection.effectiveType === '4g') {
    await import('./costly-module.js');
}

The navigator.connection object gives some information on the network. E.g. the downlink property gives you the bandwidth in megabits per second. The round-trip time is in milliseconds

Network Info

How you use this API is highly dependant on your use case. But as an example, if navigator.connection.downlink is low, you can download smaller resources instead. In an ideal scenario, this setting would be customisable however (via your webpage UI).

Note: Being on WiFi doesn't mean fast, and being on 3G doesn't mean slow. For example, think about tethering!

Browser support seems to be limited to Chromium based browsers.

Getting the network information on the server

You can also get some of that network information on your server, in the form of a network request header.

Network downlink as a request header

To achieve this, use the following <meta> tag in your main HTML file:

<meta http-equiv="Accept-CH" content="Downlink">

Subsequent requests now have the request header: downlink: 6 for example. You can also use content="ECT" to get the Effective Connection Type as a network request header.

Save-data

While you can infer context based on network information like roundtrip times and connection types, the saveData property states a device preference for reduced data usage.

if (navigator.connection.saveData === false) {
    await import('./costly-module.js');
}

This is available server side (as a client hint), and at some point it should be available as a CSS Media Feature.


Conclusion

It's not all about JavaScript, you can also use these various device details to:

  • Reduce heavy/complex animations - which can be a challenge for devices with low memory.
  • Reduce the download of heavily encoded images (e.g. AVIF) - which can be a battery drain.
  • Reduce download of network resources of any type - which can struggle on a congested network connection.

If you have any troubles viewing this animated gif, check out: umaar.com/dev-tips/242-considerate-javascript
Email Marketing Powered by Mailchimp

Copyright © 2020 Umar, All rights reserved.
You are receiving this email because you signed up for Dev Tips.

unsubscribe from this list    update subscription preferences 

Older messages

Dev Tips: DevTools: Record tests with the puppeteer recorder

Friday, December 4, 2020

A test generator for puppeteer built into Canary DevTools Dev Tips DevTools: Record tests with the puppeteer recorder 🎥️ Introduction The Puppeteer Recorder feature in Chrome DevTools can monitor your

Dev Tips: DevTools: Refactor your styles with CSS Overview

Wednesday, November 18, 2020

View different metrics on your styles and improve your overall CSS architecture Dev Tips DevTools: Refactor your stylesheets with CSS Overview Introduction The CSS Overview Panel provides interesting

Dev Tips: DevTools: Create your own keyboard shortcuts  ⌨️

Friday, November 13, 2020

The Shortcut Editor lets you assign your own preferred keyboard shortcuts to common workflows. Dev Tips DevTools: Create your own keyboard shortcuts ⌨️ Introduction The DevTools Shortcut Editor lets

Dev Tips: DevTools: The New Media Panel  🎬

Wednesday, November 4, 2020

The Media Panel in DevTools provides useful video inspection tools, useful for debugging, understanding, and learning about video. Dev Tips DevTools: The New Media Panel 🎬 I've written an article

Dev Tips: DevTools: CSS Grid Inspection ✨

Wednesday, October 28, 2020

Dev Tips DevTools: CSS Grid Inspection ✨ Hey everyone! I took a little break, but I'm back and I've got some great tips to share with you over the next few weeks! Introduction CSS Grid

You Might Also Like

AI + high-stakes poker + Google's prompt cheat sheet

Tuesday, October 8, 2024

and a google prompt cheat sheet ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏

👍 How My Phone Became My Favorite Game Console — Why Desktop Linux Matters

Tuesday, October 8, 2024

Also: iPhone Mirroring Is Here and Mostly Works, and More! How-To Geek Logo October 8, 2024 Did You Know At the end of the song "Sweet Child O' Mine," found on Guns N' Roses'

Software Testing Weekly - Issue 240

Tuesday, October 8, 2024

How Sonos Lost $200M: A Hard Lesson in Quality 🚨 View on the Web Archives ISSUE 240 October 8th 2024 COMMENT Welcome to the 240th issue! Back in June, I shared with you about the big problem with a new

Immutable Types, DuckDB & Pyodide, Free Threaded, and More

Tuesday, October 8, 2024

Differences Between Python's Mutable and Immutable Types #650 – OCTOBER 8, 2024 VIEW IN BROWSER The PyCoder's Weekly Logo Differences Between Python's Mutable and Immutable Types In this

Ranked | The Costliest Hurricanes to Hit the U.S. ☔

Tuesday, October 8, 2024

As of 2023, Hurricane Katrina is the costliest natural disaster in US history, causing over $200 billion in damages in 2024 dollars. View Online | Subscribe | Download Our App Presented by: NEW REPORT:

Daily Coding Problem: Problem #1572 [Easy]

Tuesday, October 8, 2024

Daily Coding Problem Good morning! Here's your coding interview problem for today. This problem was asked by Yelp. Given a mapping of digits to letters (as in a phone number), and a digit string,

The Race for Server Space

Tuesday, October 8, 2024

Apple's Leak, Disney's Star Wars, Google's Epic Fail, OpenAI's Space Race The Race for Server Space Apple's Leak, Disney's Star Wars, Google's Epic Fail, OpenAI's Space

Microsoft goes Go for SQL Server's CLI

Tuesday, October 8, 2024

Plus new ways to deploy Go apps, reflecting on reflection, and Windows gets high resolution timers in Go. | Together with Frontend Masters logo #​526 — October 8, 2024 Unsub | Web Version Go Weekly

⚙️ Nvidia's new Agents

Tuesday, October 8, 2024

Plus: Chipmaker delivers 100k GPUs ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌

How Does Visual Capitalist Work With Clients? 💪

Tuesday, October 8, 2024

Here's how organizations can partner with Visual Capitalist to leverage world-class data storytelling, and its strong audience and reach. View Online | Subscribe | Download Our App For 13 years,