Web App Performance

Animation Frames & Input Pending

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Web App Performance

Check out a free preview of the full Web App Performance course

The "Animation Frames & Input Pending" Lesson is part of the full, Web App Performance course featured in this preview video. Here's what you'd learn in this lesson:

Max explains why requestAnimationFrame is more performant and reliable than setTimeout or setInterval. The isInputPending property is helpful for occasionally checking if input from the browser needs to be processed during a long-running JavaScript task. If so, the thread can be released and continued later.


Transcript from the "Animation Frames & Input Pending" Lesson

>> For those of you that are using setTimeout and setInterval, there is a much better way that has been for a while now, but it's still not the way that most developers are using. It's requestAnimationFrame. It's part of the HTML5 today. And let us execute code on the next frame before painting the frame.

Remember that we saw that diagram with what's going on there. And it's guaranteed to be executed on the next frame because you know what happened with setTimeout. So setTimeout or setInterval. So if I do setInterval, and execute some code, okay? I do something here like say "Hello". And then I say 100.

What do you think that this code is going to do?
>> Console log ten times.
>> Console log ten times per second, right? Is it guaranteed?
>> No, it'll end based on where it isn't like the call queue that can-
>> Yeah, in fact, it is not guaranteed at all.

In fact, if you use instead of setInterval, setTimeout, and let's say you have a very important task that you need to do in one second. You are confident that that will work. But not really. This is how it works. So when we have that process of painting, things that we have been seeing here.

So setTimeout are actually being executed within idle callback time. Between one frame and the other frame. The problem is that what happens if there is no idle callback time? You have some code here in your input events. You have an onclick. You have something that is taking a lot of time.

So there is no idle time. The browser says no, I'm sorry, I need to make the other frame, I need to make the other frame, I need to make the other frame, and maybe it doesn't have enough time to execute your timer. So actually, every time you are saying setTimeout or setInterval, you are actually, it's not a real timer, it's not an alarm that will wake up that code in one second.

It's just setting that function in some kind of a queue in the table of call to execute in the future. And the 1000 is not a timer. It's not an alarm. It's actually an expiration date. So when the browser is doing nothing, it says, okay, let's go and see if we have something pending and he goes over the list and see if it's expired or not.

If it's expired it will execute it but maybe has expire 10 seconds ago so it's going to execute that later. And of course, that's bad for a lot of situations. So that's why it's a better idea to use request animation frame because it's guaranteed to be executed at that moment on every frame.

But your code should be short. Right, why? Because if it's too long, you will push the whole frame, and then we'll have a frame drop in the animation. So that's why we should keep that code small under 10 milliseconds of execution. It's more in execution not in size.

It's much better than timers, okay? You just request animation frame and do some code that's all and it's guaranteed is going to be executed on the next frame. Sometimes you need to do something in that diagram, but it's not really important. So if it's enough time you wanna execute that, but if not, I'm okay.

Okay, I can wait. For that, we can use that idle time if it's there. It's called idle callback. Actually, the spec is known as request background task. And in that case, you will use that time that can be long or short, you can try to use that one, okay?

For that, you use then request idle callback and you pass a function. Makes sense? It's just another way that you have to make things more performant. Something relatively new on the web is isInputPending. If you look at that diagram, it's has one specific blue color there. I'm not sure if you recognize that blue.

When I tell you why, you will recognize it. That's Facebook's blue. Because that API was proposed by Facebook. And that's from the original documentation that was proposed by Facebook. And now it's on Chrome, that API. isInputPending will give you the idea of if there is anything in the queue pending that needs to be processed.

So let's say you have a long running JavaScript you need to execute, okay? Then you end that process and at that moment, the browser has time to check if the user clicked or JavaScript, input events. But that can lead to a problem because for a lot of milliseconds or even seconds, the user didn't see any change.

Well, instead of doing that, you can split your JavaScript and every once in a while, you can check is there any input pending to the processed. And if the answer is yes, you'll release the threat and you'll continue later. So you register another request animation frame. Does that make sense?

So you leave, it's just a flag from the browser to the developer saying, I have pending things, so if you can, leave me some space. Does it make sense? That is input pending. So then you can make small spaces asking. Does it make sense? And because you're asking, you are not yielding between the browser and your code.

You're just asking, if there is anything pending, I will give you time. If not, I don't need to give you time. That's much faster, okay? This is how it works in terms of code. And it's not a big deal, we don't need to cover it too deeply, but actually, it's navigator.scheduling.isInputPending().

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