Check client (Frontend side) CPU/memory usage in JavaScript with these web API features
Last updated on March 2023
The web API has so many useful features, and I'm always finding new ones I haven't come across before. Today I found out about ways to check if a user's computer has enough RAM, or CPU.
This might be useful if you only want to run certain scripts for users on higher powered machines. Maybe for low powered machines you want to serve an alternative (less memory/cpu intensive) version.
One thing to be aware of is that using these can have privacy issues. These techniques can be used to somewhat fingerprint and identify users. Before using these functions you should also check their compatibility with modern browsers (not every feature on this page is supported by all common browsers).
Here are some live stats about your machine (works best on Chrome - some things are unsupported on browsers like FF or Safari):
All of the code to get these stats about your Frontend (FE) user's machine is described below.
Get number of CPUs in Frontend code
Your can use navigator.hardwareConcurrency
to get the number of logical processors on the user's computer.
Unlike most other exampels here, I've actually seen this in use. I've seen it used when spawning workers (a worker for each cpu core).
Technically this isn't going to return the number of cores - but number of 'logical processor cores'. Each one of these should be able to run its own thread (which is why it is useful for spawning workers, on their own thread).
console.log(window.navigator.hardwareConcurrency)
Here is a live demo from your machine:
Supported on most browsers except Safari
Get amount of memory (RAM) that your client's computer has
You can check memory usage with navigator.deviceMemory
.
It is readonly. And will return either 0.25
, 0.5
, 1
, 2
, 4
, or 8
. These values are approximate. The reason for returning these instead of an exact amount is to restrict fingerprinting
The reported value is imprecise to curtail fingerprinting. It's approximated by rounding down to the nearest power of 2, then dividing that number by 1024. It is then clamped within lower and upper bounds to protect the privacy of owners of very low- or high-memory devices.
This is the output for your machine (if you are on Firefox/Safari it will not work):
console.log(navigator.deviceMemory);
It is supported in Chrome/Edge/Opera, but not in Firefox or Safari. See specs here.
Check user's remaining battery
You can call navigator.getBattery()
to get stats about the user's battery.
I cannot recall seeing this in use, but I can see how it would be useful and I'm sure there are websites I use that make use of this.
This returns a promise, and there are several attributes you can pull out of it. (It returns a BatteryManager
object).
console.log(await navigator.getBattery());
/*
{
charging: false
chargingTime: Infinity
dischargingTime: 10080
level: 0.81
onchargingchange: null
onchargingtimechange: null
ondischargingtimechange: null
onlevelchange: null
}
*/
You can also listen to events to be notified when charging starts/stops:
let batteryIsCharging = false;
navigator.getBattery().then((battery) => {
batteryIsCharging = battery.charging;
battery.addEventListener("chargingchange", () => {
batteryIsCharging = battery.charging;
});
});
You can find more details about the BatteryCharging api here.
Browser support is not great, but supported well in Chrome.
Get information about client's internet connection.
You can use navigator.connection.effectiveType
to get the effectiveType of connection.
This is a very rough estimate on the type of connection the user could be on, based on recent internet speeds.
It returns a string, and the values can be one of: slow-2g
, 2g
, 3g
, or 4g
.
console.log(navigator.connection.effectiveType)
You can also check the "effective bandwidth estimate in megabits per second, rounded to the nearest multiple of 25 kilobits per seconds" with navigator.connection.downlink
.
Although not in the specs, most browsers will return a maximum of 10mbps.
console.log(`Your download speed: ${navigator.connection.downlink}mbps}`)
It doesn't have great browser support but does work in Chrome.
Demo:
A useful attribute to be aware of is navigator.connection.saveData
. If true then the user has set reduce data usage on their machine/browser. See more about the related Save-Data HTTP header here too
Check the client's storage
If you have large downloads, you could check the user's storage to help decide if you want to offer larger downloads.
You can access that (in supported browsers) with navigator.storage.estimate()
console.log(await navigator.storage.estimate())
/*
{
"quota": 399999999999,
"usage": 0,
"usageDetails": {}
}
*/