DEV Community

Yaser Adel Mehraban
Yaser Adel Mehraban

Posted on • Originally published at yashints.dev

Page Visibility API, let's help users save their battery life and data πŸ˜€

Are you want of those people with 200 tabs open? Are you tired of carrying your laptop charger with you all the time? Well, I am here to let you know we can help users save battery, data, and time, if we know how to use the Page Visibility API.

The why

Imagine your user has a few tabs open, one running a heavy animation, the other getting a lot of data from the server, and another running a video from YouTube. These all require resources from user's computer and that's why sometimes having a few tabs open you suddenly realise you're running out of battery, or your data allowance is finishing.

πŸ’‘ What if you could pause the current operation on a tab/window if the user isn't looking at it?

With Page Visibility API, you can do that.

Page Visibility API

This API allows a developer to become aware if the user has lost focus on the page, or has returned to it again. When the user minimises, or switches to another tab/window, the API sends a visibilitychange event to let the listeners know the state of the page.

Page Visibility API is a very useful tool in your toolbox which gives you the power to not perform unnecessary operations when the page is not visible to user.

This API adds the following properties to the Document interface:

  • hidden: which is a read-only attribute and returns true if the page is in a state to be considered hidden to user.
  • visibilityState: which is a DOMString indicating the document's current visibility state. It can have four values, visible, hidden, prerender, and unloaded.

You can also listen to the visibilitychange event which will trigger your callback function whenever the visibility changes:

function handleVisibilityChange () {
    if (document.hidden) {
        // stop that task πŸ›‘
    } else {
        // you can start it again go ▢️
    }
}

document.addEventListener('visibilitychange', handleVisibilityChange, false);
Enter fullscreen mode Exit fullscreen mode

visibilityState

As mentioned before, this property can have four different values each of which representing a different tab/window state:

  • visible: This means the tab/window is visible or partially so. In other words, it means the page is the foreground tab of a non-minimised window.
  • hidden: Page is not visible due to being minimised or the device's screen is off.
  • prerender: The page is now being prerendered and is not visible to user.
  • unloaded: This means the user is about to close the current page.

⚠️ You need to know that not all browsers support the last two states.

Demo

The simplest scenario is playing video on the page, so we will be using that as an example. Let's use a simple video element on the page which will be paused when the user focuses on another tab.

<body>
    <h1>Demo: Page Visibility API</h1>

    <main>
        <video id="videoElement" 
               poster="http://media.w3.org/2010/05/sintel/poster.png" width="400"
               controls="" >
           <source id='mp4' src="http://media.w3.org/2010/05/sintel/trailer.mp4" type='video/mp4'/>
        <source id='webm' src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm'/>
        <source id='ogv' src="http://media.w3.org/2010/05/sintel/trailer.ogv" type='video/ogg'/>
            <p>Sorry, there's a problem playing this video. Please try using a different browser</p>
        </video>
    </main>


    <script>    

    (function() {
        'use strict';

        // Set the name of the "hidden" property and the change event for visibility
        var hidden, visibilityChange; 
        if (typeof document.hidden !== "undefined") {
          hidden = "hidden";
          visibilityChange = "visibilitychange";
        } else if (typeof document.mozHidden !== "undefined") { // Firefox up to v17
          hidden = "mozHidden";
          visibilityChange = "mozvisibilitychange";
        } else if (typeof document.webkitHidden !== "undefined") { // Chrome up to v32, Android up to v4.4, Blackberry up to v10
          hidden = "webkitHidden";
          visibilityChange = "webkitvisibilitychange";
        }

        var videoElement = document.getElementById("videoElement");

        // If the page is hidden, pause the video;
        // if the page is shown, play the video
        function handleVisibilityChange() {
          if (document[hidden]) {
            videoElement.pause();
          } else {
            videoElement.play();
          }
        }

        // Warn if the browser doesn't support addEventListener or the Page Visibility API
        if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
          alert("This demo requires a modern browser that supports the Page Visibility API.");
        } else {
          // Handle page visibility change   
          document.addEventListener(visibilityChange, handleVisibilityChange, false);

          // When the video pauses and plays, change the title.
          videoElement.addEventListener("pause", function(){
            document.title = 'Paused';
          }, false);

          videoElement.addEventListener("play", function(){
            document.title = 'Playing'
          }, false);
        }

    })();
    </script>

</body>
Enter fullscreen mode Exit fullscreen mode

All we're doing is to get a reference to the video element and hook into the visibilitychange event. When the page is hidden, we simply pause the video. Once the focus is back in, we play it.

Simples

I've create a live version on Glitch you can have a look. Play the video and click on another tab. The video will get paused and once you're back, it plays again.

Summary

A good web application does not necessarily require hot features and impressive UX. Sometimes a performing web application would appeal to users like no other. Hope this little article helps you help your users in many ways.

Happy exploring 😊.

Top comments (4)

Collapse
 
mazentouati profile image
Mazen Touati • Edited

Indeed, this feature is powerful and may be used for good deeds. However, I hate it very much (I mean from user point of view) because now companies like Facebook use it to force users watch Ads or live videos. Others may try to be smart and decide what to pause and what to not pause which may lead to unwanted results. Sometimes, I'm fine with videos playing in the background it may be a music video or a talk show or whatever. Also, one big downside is that it does not work well with multi-monitors setup. When I focus in another monitor the hidden event will be fired which is very annoying. At least, users should be allowed to decide whether they enable it or not within the web app setting.

Collapse
 
yashints profile image
Yaser Adel Mehraban

All valid points, but as developers, we have the choice of using this for good or to annoy users.

With great power comes great responsibility 😊

Collapse
 
frandall profile image
Andry Kurniawan

Well thanks, for sharing this, by knowing this feature, at least we as a developer can make script to help protect user against those evil ^

Collapse
 
mazentouati profile image
Mazen Touati

Yes, another double edge weapon πŸ˜€