Quick Tip: Working with the JavaScript Battery API

Demo Download

In this tutorial we're going to show you how to use the JavaScript Battery API to improve the user experience for people in desperate need of a charger. We'll look at the Battery API itself, as well as some techniques for getting the most out of every drop of the most precious of resources!

Monitoring Battery Life

The JavaScript Battery Status API talks to the device's hardware and gives us accurate data about the system's charging state. It can be accessed via the promise based navigator.getBattery() interface, or directly via the navigtator.battery object, although the second option is now deprecated and overall not recommended.

Some browsers lack support for the Battery API (you guessed it, they are Safari and IE), so a quick support check can go a long way in terms of debugging:

if(navigator.getBattery){
    // Battery API available.
    // Rest of code goes here.
}
else{
    // No battery API support.
    // Handle error accordingly.
}

Once we are sure that your user can access the API, grabbing the needed information is really easy:

navigator.getBattery()
    .then(function(batteryManager) {

        // Get current charge in percentages.
        var level = batteryManager.level * 100;

    })
    .catch(function(e) {
        console.error(e);
    });

The getBattery() method returns a promise and resolves with a BatteryManager object containing various information about the current status of the hardware:

  • batteryManager.level - The current charge, returns a float between 0 and 1.
  • batteryManager.charging - Is the device on power supply or not, returns true/false.
  • batteryManager.chargingTime - Remaining time in seconds till completely charged.
  • batteryManager.dischargingTime - Remaining time until battery is dead.

It also provides events that can be used to monitor changes in any of the above properties.

  • BatteryManager.onlevelchange
  • BatteryManager.onchargingchange
  • BatteryManager.onchargingtimechange
  • BatteryManager.ondischargingtimechange

Combining the raw data with the event listeners, we can easily set up a watcher for low battery levels:

navigator.getBattery()
    .then(function(battery) {    
        battery.onlevelchange = function() {

            if(battery.level<0.3 && !battery.charging) {
                powerSavingMode = true;
            }

        }
    });

Once we know how much juice is left in the device we can adapt the app and turn on a power saving mode if its needed.

Preserving energy

The biggest battery drainer of all components is the screen. This is especially true on smartphones and tablets where often CPUs are energy preserving, while the screens have super-ultra-full-QHD resolution with the brightness of two suns.

The first and foremost thing we can do to address this issue is limit the amount of light the screen is emitting. JavaScript doesn't have the authority to control the brightness directly, but we can do so by changing the color pallet to a darker theme.

dark-theme.png
Dark colors need less energy to be displayed, with more than 50% reduction on AMOLED screens.

The next thing we can do is limit the amount and size of requests to external resources. The biggest drainers here are high-res images, advertisements, and large JavaScript libraries, as they need a lot of bandwidth to download.

Here we have two options - load an alternative, more optimized resource with a smaller footprint, or, fully remove the image/advert if it doesn't portray any essential information. Any background images, videos or animations should be removed.

removed-ads.png
Removing non-essential elements from the page makes the vital content easier to reach when in a hurry.

The last battery-drainer we will talk about is JavaScript. We already mentioned that download large libraries and frameworks is bad enough, but the actual parsing and execution of JS block can also lead to unnecessary spending.

JavaScript animations that cause constant redrawing of elements on the screen, listening for notifications form the server, and multiple AJAX requests can all drain the battery just a tiny bit, but it quickly adds up. According to this study, the JavaScript code consumes ~7% of Yahoo's total rendering energy, ~17% on Amazon, and more than 20% on YouTube.

App With Powersaving Mode

We have showcased some of the above concepts in a simple demo app. It consists of a static website which reacts to the amount of battery left. When it gets below 30% the app goes into PowerSaving and turns darker, stops all animations, and removes all ads.

For demonstration purposes our app works with a virtual battery to enable quick toggling between fully charged and almost dead. It does not contain much code for working with the Battery API itself.

battery-demo.png
Our Demo App

You can get the full code for the demo from the Download button near the top of the article. It's written in Vue.js for easier data monitoring and has lots of comments to guide you through all that is happening.

Further Reading

If you want to find out more about the Battery Status API or about ways your precious battery is running down the drain, check out these excellent resources:

Battery Status API on MDN - here
The BatteryManager interface on MDN - here
5 Ways to Improve Battery Life in Your App - here
Who Killed My Battery: Analyzing Mobile Browser Energy Consumption - here

Presenting Bootstrap Studio

a revolutionary tool that developers and designers use to create
beautiful interfaces using the Bootstrap Framework.

Learn more
Web Browser Frame DevKit Box Mouse Cursor

Related Articles

This discussion is closed.

Hello! Thank you for the article! What about browsers compatibility with battery api ?

Hi Akkis!

According to caniuse support is not the best right now. Safari, IE, and Edge lack compatibility.

Never knew about this before, but I'm sure this will come handy someday.
Many thanks Danny, keep up the good work.

if(battery.level<30 && !battery.charging) {

May be you mean if(battery.level < 0.3 && !battery.charging) {?

Oh, you are right. Thanks Denis.

Luis Cabrera

Thanks! But why batteryManager.chargingTime returns Infinity?

If your device is running on battery power, chargingTime will be infinity, as it will never charge since it's not plugged in.

Once the charger is connected, chargingTime should be the approximate time in seconds till 100%.