The requestAnimationFrame API allows developers to ask the browser to make visual updates at the most optimal time. This is often used for animating objects but could apply to any visual update that's supposed to occur periodically.
(Oriental flute music) - How many of you have heard of requestAnimationFrame? Okay, so maybe about a third of you again, requestAnimationFrame is an interesting API because it was designed to fix a problem and that's where the name came from, but I really think this is an example where the name is actually a really terrible name. I think it's a really poorly named API.
So, first of all, it's not just about animation even though the API says the word animation in it. Many people think, oh, the only thing I ever need to worry about is animation. I'll point you to a blog post that I just recently did, if you search on my blog, it was a month or two ago. I talked about doing requestAnimationFrame for just plain old normal visual updates. So, requestAnimationFrame is basically an API that says, I've got a function that I am going, inside of that function I'm going to make some visual updates to the page.
I'm going to move a box around, or whatever. It's not about animation, I'm just going to show something or hide something, or make something bigger, or drop in a banner, or pop a dialog, whatever. Any time you're going to make some sort of visual update usually CSS based, you can say to the browser, here's the function that's going to do that update and I would like you, browser, to call this function at the most optimal time for a visual update to occur. Because if you think about it, if you write your code in such a way where you are declaring "I want you to update this code right now." The browser oftentimes has to assume that you really do want it to update right at that moment.
So if you're running on a 60 hertz monitor, your browser is going to be running an update, generally speaking, it's going to be trying to update at about 60 times a second unless something's slowing it down. If you use the same browser, same system on a monitor with 100 megahertz, 100 times a second, in general those newest most modern browsers are capable of updating at faster speeds to keep themselves in sync with your display. But if you're updating your code, if you're updating, if you're making changes to your CSS in different intervals than what the browser's updating, then now you have three different potential updates that could be out of sync.
And so any time you've ever done anything with setTimeout based animations, or any time you've just made a plain old visual update at any time, you've been doing so slightly sub-optimally. And requestAnimationFrame is a nice API because it says, I don't know when that's going to happen. It could happen one millisecond from now, it could happen five milliseconds from now, it could happen an ancient 16.7 milliseconds from now. I don't know when the next update's going to be. So I don't want to take time to worry about running my update now.
I want the browser to automatically call my function for the visual update right before it does its next repaint. That way I can be in sync with that update. If it slows to 30 times a second, my code slows to 30. If it speeds up to 100, my code speeds up to 100. You get the point. So requestAnimationFrame is a really nice API not only just for animations, but for any sort of updates that you're going to do, you're going to pop in a dialog or whatever. You might want to consider queuing those things up with requestAnimationFrame. But I said the API name is really kind of poorly named because it implies that we are requesting some sort of animation frame update and my anecdotal evidence for this is, at one point about a year ago, I logged on to the MDN website and I looked up the page for requestAnimationFrame.
I wanted to know something else about it, but I noticed, I just glanced, I noticed that the very first sentence of that documentation page said something to the effect of: requests the browser to schedule a new animation frame. And I read that and I thought, that doesn't sound right. I feel like I'm pretty familiar with how requestAnimationFrame actually works and that doesn't sound even remotely like what I think it should be saying. And so I did some research, I asked some people at Mozilla and it turns out, somebody was making that documentation for that page and was completely mistaken on what requestAnimationFrame actually does.
And I think, again, anecdotally, part of the problem was that the name implied something about requesting animation frames when that's not really what's happening. The browser's going to continually repaint all the time and all you're really doing is queuing up a visual update to occur at the next paint. So what should they have called that? They should've called it, you know, visualUpdate or queueVisualUpdate or, you know, performVisualUpdate, or something. But requestAnimationFrame is just a bizarre thing. The point is, you use requestAnimationFrame any time you're making any sort of visual update that you want to make sure you're doing so as performantly as possible.
So I created a facade for the animationFrame API. As you would expect, it's called animationFrame as you see there on line one. Now, I fixed some of the conceptual problems by naming my methods queue, because that's what you're doing, you're queuing up a function to be handled at the next repaint. So you call aFrame.queue to queue up a function and there's this other subtle thing that sometimes you find yourself needing to do because there's some times where you need to make one visual update, and then you need to do another visual update, and you need those things to happen in different animation frames.
In other words, in different repaints. Because if you do them in the same repaint, like for instance, turning something red and then turning it blue. Guess what the CSS engine likely will do. It will never show the red and it will combine it and only show the blue. 'Cause you'll never have a chance to see the red. If you wanted it to flicker from red to blue, you need those things to happen at different times. Another example is if you want to show something, and then use a transition for it to pop up and then move. If you do those in the same animation frame, if you make it pop up and you apply the transition so that it will animate itself and move, if you do that, what you will get is at some point when the animation has completed, it'll just pop visible in the end location.
It won't pop and move, it will just pop up in the old location which is not what you want. So, this was a common enough task that I was running into that I realized, well, you kind of need to request not only the next animation frame, but the one after that. The next, next animation frame. And so I added that method directly onto the facade called queueAfter. So it just essentially does two requestAnimationFrames nested in each other for you. So line 11, you can do queueAfter and queue and so forth. You can cancel these things just like you can cancel any other intervals.
But it should make it pretty simple for you to deal with doing visual updates, and that's the goal.
- HTML5 facades
- Using APIs
- File I/O
- The asynquence library
- Publishing npm modules
- Grunt and Gulp
- Node as a web server
- Simulating asynchronicity
- Making a socket connection
- User-triggered messaging
- Signaling and data channels