JavaScript in the Background

Coding Visibility Change

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
JavaScript in the Background

Check out a free preview of the full JavaScript in the Background course

The "Coding Visibility Change" Lesson is part of the full, JavaScript in the Background course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano walks through the contents of the course repository, repo setup instructions, and live codes an event listener to detect visibility changes. The method covered in this segment uses the Page Visibility API.


Transcript from the "Coding Visibility Change" Lesson

>> Okay, so workshop time. Now it's time to write some code. We're going to actually write that code and see that code in action. For that, remember that you have, I will show you that again just in case, the URL. That's So get that repo download the ZIP file, doesn't matter.

And there I will show you what we have. I will open VS Code, I already have it here. Let me first get into the folder. This is the folder that you will get. By the way, let me show you what you will have in that package. While you have the slides, PDF version of the slides.

What about HiddenCam? There is a HiddenCam project there. That's the one that it's testing what happens in the background. In case you want to play with that later it's these brushing, this one. But I recorded some videos so it will be better for these. And then you have background-final and initial.

Recommend you start with initial but in case you want to get the final code. For whatever reason you don't wanna code with me, you have the final version there. I'm going to open background-initial here. That includes a pretty simple for now, node.js server that I will show you later why we need that server.

It's mostly for the web push part because that's server side, this one. And from here I will open a terminal and run npm install. So it will install the dependencies and after that npm start. This project has a server. You can see the server later we are going to see what's inside.

That for now is rendering the public folder with an html CSS and a couple of JavaScript files. But there are a lot of holes here that we are going to fill during the rest of today. Trying to open opening this is localhost 4000. You can change the port if you don't like that one.

This is what you're going to get. Background Execution and a couple of buttons to test different APIs that are empty. So they are doing nothing right now. The only thing that I already have is that if I open here a console, just to show you, I can actually call a log function.

The log function will actually send a message to a little low that we have there. So we can actually see what's going on in our APIs, okay? It's just a text area and it's adding elements inside, nothing really, really complicated. Hello Frontend Master, it appears there. It's just that, so we are going to use that API to see what's going on.

The first thing that we want to do here is to test our Page Visibility API. That's the API that will tell us where we are, if we are going to hide the window or if we are going back to the window. For that I will open in a scripts background.js.

You see that it's kind of empty with a couple of placeholders. The idea is that here we are going to play with the Page Visibility API first. Again, this is the API that we will use to detect if we are going into the background or coming back to the background.

And we can use this to stop timers to make decisions, to save data, or whatever. Well in the Page Visibility part, I'm going to say window.addEventListener, and the name of the event is visibiltychange. Remember event names are all lowercase, no snake case, or no underscore, nothing. We're going to create an event handler for it.

And here again, we need to check the document.visibilityState. And we're going to check, for example, if it's hidden. That is that We are in the background. Actually, are we going to the background or are we in the background? Actually, we are already in the background, okay? So this is executed, not before.

Actually, you cannot prevent default. We are not preventing going to the background. We are in the background, we have just arrived in the background of space. And if not, we are back from the background. That's the simplest algorithm. Of course you there are many other options that you can do here but the simplest algorithm is this one.

Something that I can do here, for example, if I go into the background, we can create a constant. We can call it now, that will create a new Date, and we're going to get the Locale. I'm going to say toLocale, not get, TimeString. Then we can log that we are Going to the background at now.

So it will give us the time. I'm using the backtick. This is a template string of ECMAScript. I'm just taking the current time and sending that to the log. If I save this and we run this we're going to start seeing if this is working. So, going back to a browser, any browser, it doesn't matter.

If you refresh, and then for example, you open a new tab and you go back. You can see that it went to the background at that time. And you can see that even the two to three seconds that we have on iOS is enough to execute this handler, okay?

So even in iOS, this is going to be executed even if you press the home screen. The only situation where this event is not going to re-fire is if you kill the browser's process or the PWA process from the Task Manager. If you kill the browser you're killing the process.

The browser will not even have time to execute your event handler, make sense? That's the only situation where this event handler won't be fire. Of course here we can do the same log. But something maybe more interesting is that when you're going back from the background. Something that you may want to know is how much time has passed from the last session.

This is a pretty common use case, because maybe the user is going back to your web app a minute after. So it's coming from the background a minute after. Or maybe it's a day, or maybe it's a week. If you have enough RAM in your phone, and you haven't opened so many other apps.

Maybe a week later, you go back to the PWA and it was still there. And of course, it's not the same. It depends on your app. It depends on what you're doing in your website. If one week has passed, maybe you want to do something else, reload the page.

Or you don't want to restore the state because maybe you're a newspaper and of course everything is old there. It doesn't make any sense. It depends on the product that you're creating what you're going to do here. A simple way that you have to actually detect how much time has passed is that we can create a global variable.

Of course we can do this better with our op or whatever, but we can call this backgroundInitialTimestamp. When we are going to the background, I'm going to say that I need the Timestamp. By the way, do you know how to get a high performance Timestamp in JavaScript? Actually you can use the new Date and get the Timestamp, but that's actually not really accurate.

Also it's taking some time because it's creating an object in JavaScript to actually taking the time is changing the observation. It's, so it's part of the-
>> We just started using that and it's really cool.
>> It's really cool. Yeah, it's high performance so it's giving you precision in nanoseconds.

So nanoseconds is actually a lot of precision. And now but actually when we are here we need to just create the constant for how much time has passed. Something like this so we are going to say it's another performance- the InitialTimestamp, okay? Something like this but this is in milliseconds, it's fine.

But it's a millisecond but it's a float value, because the precision is up to nanoseconds, actually. Maybe what I want is just the integer part of it. I can also round with Math.round. Let me put that here, something like that. And then I can log how much time has passed.

We can say We are back from the background. After timeElapsed, and we can say this in seconds, something like that. Again, you use that time to know how much time has passed since last session. Again, if it's a matter of hours, days, minutes, seconds, anything can happen here.

Make sense? There you're going to use that thing to make a decision. Are you keeping the session? Maybe even you need to revalidate your auth authentication token, who knows? Make sense, because maybe you are coming back from a hibernation and suspension state. So you were suspended and now you're coming back any time.

In fact think about this on desktop a browser session. Have you ever used session storage? This is part of the web storage API. It's similar to local storage, but the data leaves only within the session, within the browser session. If you close the browser, everything in session storage will be cleared out.

So a question for you, what's a session? What's a browser session in a mobile device? What's the lifespan of a browser session? Are you closing the browser? When do you close the browser on iPhone or Android? You don't close it. You just press the home screen button or you go to the home screen with the Chester.

If you go in back, is it the same session or not? So what's a session? It's not so simple. That's why session storage and mobile devices are completely useless. Because the session as a concept in the browser doesn't exist anymore. And we have there the same problem. Maybe two weeks after the browser will tell you it's the same session because the browser was still there.

Because you never closed the browser. Something similar happens here. If you don't have any typo, any errors, if I try this. If I go to a new tab and come back, it's showing me the data. I can increase this a little bit. And that also happens if I minimize the browser then I open the browser again.

It's giving out when you go back, when you get out, when you go to the background, when you're going back. Yeah, question?
>> What about closing the tab and then reopening it?
>> That's a good question. If you close the tab, I can try that but what will happen is that we won't see the data because I'm not saving the data here.

In fact, look at that, I was really fast enough to actually see that happening. So it says NaNs, so, what's going on? That's a new page navigation. It's a new page navigation. One is getting out and another one is getting in. It's a different page navigation, so technically you're getting out of that app and that app is actually discarded completely.

It's a new page navigation. A new page navigation will always be a new app instance. So in this case, if you have that use case, maybe the option is to use. To store the data, to store the state and restore the state here. This is actually a completely new page navigation.

If you close the app and you open the app again, I mean, you have a PWA, if I have it still here. Let me see if I have it, if you open a PWA. This one, this is a PWA. Let me show you this. Let's install a PWA on iOS, Squoosh.

That is a PWA to reduce the size of images and because it's a PWA I can install it. Then I can open my PWA. The question is what happens if I close the window? That's the window for the current PWA, and open the app again? It's a new page navigation.

I'm not going back, it's a completely new page navigation. And the same happens if you close the tab and you open the tab again. Make sense? Cool, well, there are more to see about the page navigation API. But with just these codes, you're covering probably 95% of your use cases, if not more.

It can get more complicated but typically with this, it's enough.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now