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

Stay compliant without compromising productivity

Thursday, November 21, 2024

Join us on December 5th ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏

Spyglass Dispatch: Comcast's SpinCo Out Hunting • NVIDIA Makes Mint • The Fate of Chrome • Amazon Shows New 'Show' • End of Around the Horn • Writing on the Web

Thursday, November 21, 2024

Comcast's SpinCo Out Hunting • NVIDIA Makes Mint • The Fate of Chrome • Amazon Shows New 'Show' • End of Around the Horn • Writing on the Web The Spyglass Dispatch is a free newsletter sent

Issue 340 - Elon Musk hints at a new model for large families

Thursday, November 21, 2024

View this email in your browser If you are just now finding out about Tesletter, you can subscribe here! If you already know Tesletter and want to support us, check out our Patreon page Issue 340 -

Data Science Weekly - Issue 574

Thursday, November 21, 2024

Curated news, articles and jobs related to Data Science, AI, & Machine Learning ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏

Programmer Weekly - Issue 232

Thursday, November 21, 2024

View this email in your browser Programmer Weekly Welcome to issue 232 of Programmer Weekly. Let's get straight to the links this week. Quote of the Week "Writing software is a very intense,

Better - An AI Powered Code Reviewer

Thursday, November 21, 2024

Top Tech Content sent at Noon! How the world collects web data Read this email in your browser How are you, @newsletterest1? 🪐 What's happening in tech today, November 21, 2024? The HackerNoon

Python Weekly - Issue 677

Thursday, November 21, 2024

View this email in your browser Python Weekly Welcome to issue 677 of Python Weekly. Let's get straight to the links this week. From Our Sponsor Get Your Weekly Dose of Programming A weekly

Web Tools #592 - JS Libraries, Git/CLI Tools, Media/SVG

Thursday, November 21, 2024

WEB VERSION Issue #592 • November 21, 2024 Advertisement Deploy AMD Instinct™ MI300X on Vultr AMD Instinct MI300X accelerators are now available on the Vultr cloud platform. With thousands of AMD

Stop Using the Wrong State Management in Jetpack Compose

Thursday, November 21, 2024

View in browser 🔖 Articles Benchmark Insights: Direct State Propagation vs. Lambda-based State in Jetpack Compose Here, we'll dive into some benchmark analysis on the state propagation approach in

wpmail.me issue#694

Thursday, November 21, 2024

wpMail.me wpmail.me issue#694 - The weekly WordPress newsletter. No spam, no nonsense. - November 21, 2024 Is this email not displaying correctly? View it in your browser. News & Articles State of