>> To understand what's going on on different operating systems, we need to spy what's going on in the background. So spying a web app in the background is not so simple using standard developer tools, because some of those tools will also be disposed when your website is disposed.
[00:00:18] Anyway, I created a really quick tool to actually spy on what's going on with a socket, and I mean, you have the code in their repository in case you wanna play with that later. I have here a couple of videos to actually show that in action with different browsers.
[00:00:35] So we can actually understand what's going on with frames per seconds. So in case you have an animation, so what's going on with the frame, right, on different situations? On timers, so if you have a timer that is doing something every ten seconds or every ten milliseconds, so what happens when your app goes to the background with those timers?
[00:00:58] What happens if you have a web worker, a thread, okay, and that thread is also doing stuff? And it can involve also timers in the web worker thread, okay? So what happens, because, I mean, the user never sees threads. So the user is not seeing a thread, the user is seeing the website.
[00:01:17] That website maybe opening different threads. So what's going on with those threads? And also service worker. So, the service worker, it's actually different from a web worker attached to a page navigation. And the service worker is a thread, but it's not attached to a page navigation. So that's the first main difference.
[00:01:39] So, for that, I did a little dashboard, okay, we'll show you that in action [LAUGH] in a minute, where we can actually see in action running. We can run a URL in a browser, play with it, like hiding the website, hiding the window, making the window appearing again, and see what's going on here with frames per second in Request Animation Frame.
[00:02:03] Request Animation Frame is an API that we can use to actually get executed some code on each frame of the animation. Then I also do the same thing with frame per second on CSS animations. So see what's going on if you have a CSS animation, or a CSS transition, that is also an animation.
[00:02:23] So what happens when it's in the background, and also the timer frequency. Okay, and I have the same for a worker thread and a service worker. So we can see what's going on, okay? So let me show you this in action. For example, this is a video, so I've already done this so we can do this quicker.
[00:02:43] So actually you can see this is Chrome on desktop, in this case on a Mac, but it's the same on the rest of the desktop operating systems. So you can see that by default when you have that website in the foreground, everything is at 100%. So we can see everything here is 100%.
[00:03:03] The frames per seconds, and the timers, everything is working as fast as possible. But as soon as we open a new tab, for example, you can see how that is changing. So first, because now my, let's say website, is hidden, okay, before it was actually visible. So at one point it's hidden.
[00:03:32] You can see that, first, everything that has to do with animations goes to zero. So your request animation frame code will never be executed again while hidden. And also the timers are going down. So the frequency is going down. So actually if you have a timer that executes code every ten seconds, if the website is hidden, the browsers today, at least, they are actually also decreasing the frequency.
[00:04:04] It depends on the browser, it depends on the OS. The idea here is to save battery on websites that the user is not actively using at that point. Okay, so ten years ago, this was not the case, actually, your timers were all 100%. It doesn't matter if the website's hidden or not.
[00:04:26] So if you look at the worker thread, it's still at 100%. So that frequencies, the timer frequency is not changing for worker threads, or service workers, okay, makes sense? So only for everything that you have in the main context, yeah.
>> So just to clarify, if you have a timer do something every ten seconds, if that is hidden, it will not stop doing that action every ten seconds?
>> Yeah, that's correct. In fact, the set time out or set interval, they're not guaranteeing you that it's going to execute that code at that particular time. Actually, what happens is that the code that you specify in a set timeout or a set interval, goes to a queue of pending tasks with some kind of an expiration date.
[00:05:16] And that's the time that you define. I mean, if you say ten seconds from now, the expiration date will be ten seconds from now. But the browser is not guaranteeing you that you will execute this in ten seconds. It will be after the expiration, whenever the browser decides that there is time to execute that queue, okay?
[00:05:33] So in this case, what happens is that when your page is hidden, it's changing the algorithm that goes through that list and says, you know what? I'm not going to check that every every one millisecond, I'm going to check on every frame. I'm not going to check that on every frame, I'm going to check that once per second.
>> But it's not going to zero, right?
>> It's not going to zero for now.
>> For now?
>> For now, because it depends on the situation because you can also minimize the whole window, okay, and you can wait a couple of minutes. And also it depends on the browser, okay?
[00:06:11] So I have a diagram in a couple of slides, about my research on how that works on every browser, but it can change on new versions of Chrome. In fact, Chrome 108, I think, has a new flag that for now it's experimental, that they are changing this. So they're trying just to push you into stop using timers in the background, so they're going to change this algorithm again probably in a year or something like that, okay, yeah.
>> If you come back to the tab and there is something in the queue, will it execute right away?
>> Look at this. So if I go back to the tab, I'm doing this right now, everything goes back to 100% again. And what happens with the queue? This is Firefox.
[00:07:01] Let me stop here in Chrome. So what happens with the queue, that's your question? So it depends if it's a set timeout or a set interval, but actually it will execute your code, your pending code, but once, okay? Because the idea is that, I mean, if you were expecting to execute a code 60 times per second, and it's decreasing the frequency, it's not going to execute your code 60 times after the second has passed, only once, okay?
[00:07:30] So that's how set interval works. So it needs to first parse one, so the next tick before actually scheduling the next one. So if it happen that you're within, we haven't seen that yet, but if your website is suspended, and you're coming back a day after, okay? Even if your set interval was set as once per second, it will execute that after a day, okay?
[00:08:06] Because again, yeah, the queue has that exploration. It expires, so let's execute the expired task. But that's all, okay? Firefox, is it Firefox on desktop as well, it's kind of similar as well. So, if I do this, I mean, you can see that the timer frequency goes down.
[00:08:27] But also there are some other situations, because, for example, if you cover your window, it also goes to hidden. That doesn't happen in Chrome, that happens on Firefox. So here I just wanna show you that this is a completely different on every browser, this is a fiery on a Mac, okay?
[00:08:46] So Safari on the Mac, well, it's also doing something like this, but it's more aggressive. And by the way, Bernie, you have heard Tim Coke saying that Safari saves more battery and blah, blah, blah. This is one of the reasons why it's saving more battery. So because it's actually stopping the whole thing, and your timers are actually stopped at all.
[00:09:10] Your service worker is stopped actually like two seconds after you get out of that website, and also your worker threads. So, yeah, it saving me more battery because it's executing less code from websites that are not actually the active tab. And actually probably you have seen that. There are a lot of Chromium browsers out there also claiming that they are saving battery, for example, Brave.
[00:09:37] Well, they're changing the Chromium algorithm for this, for background types as well. So that's one way they have to save battery, okay? They're just pausing or they are, we haven't seen the concept yet, but they are suspending a tab. So that tab is not executing any code any time, or any thread.
[00:10:03] Nothing until you go back. Okay, if you go back, I'm going back here, yeah, everything goes back to green. So, on desktop operating systems, your web app won't be visible if it's a background tab, if the browser is in the background, if the PWA is in the background.
[00:10:22] And on some browsers such as Firefox, it also happens when you totally cover the window, okay, with another OS window. In this case, all web apps are open, they are in memory with execution rights, okay? And web apps that are not visible may limit the timers. It depends on the browser.
[00:10:48] For example, Chrome, okay, it's actually limiting to start simple for ten minutes. So for ten minutes, you can actually execute some kind of ten timers per second for the first ten minutes. After that, it goes to one per ten seconds. So your timers are even going worse, okay, after ten minutes of inactivity.
[00:11:16] So, yeah, the timer is in the background for ten minutes, the user never came back. Your timer, now it's going. You can execute one set time out or one set interval per ten seconds, okay? And also as I mentioned before, when your context is in the background, some browsers may suspend the whole tab.
[00:11:40] And suspension means that it's in memory with no execution rights at all, okay? For example, Brave is doing that. The service worker has its own lifecycle. Later we will go over that, and we will see that in action with our code. But service worker typically is different. Safari is the only one that is really aggressive with service workers as well.