My understanding is whenever there is some DOM manipulation like inserting a DOM element would trigger a reflow and most likely followed by a repaint. Please correct me if I'm wrong. Quoting the MDN Web Docs,
The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint
the requestAnimationFrame (a.k.a. aAF) callback is called just before the browser is about to repaint. So does this mean if we somehow manage to do a DOM manipulation inside this rAF (edit: and also queue another rAF at the end) which triggers a reflow everytime and thus a repaint, we would be stuck in an infinite loop without actually rendering anything on the screen.
Or is it the case that once the browser had decided to do a repaint, it will stick with it and apply any updates that happened in the RAF callback in the next repaint?
whenever there is some DOM manipulation like inserting a DOM element would trigger a reflow and most likely followed by a repaint
The painting action occurs asynchronously, so "trigger" should be understood in that way. First your JavaScript code will finish before that actually happens.
if we somehow manage to do a DOM manipulation inside this rAF (edit: and also queue another rAF at the end) which triggers a reflow everytime and thus a repaint, we would be stuck in an infinite loop without actually rendering anything on the screen.
The needs for repaint accumulate and are not synchronously fulfilled. First your code has to complete until the call stack is empty. So there is no infinite loop here.
Or is it the case that once the browser had decided to do a repaint, it will stick with it and apply any updates that happened in the RAF callback in the next repaint?
Yes. When the RAF callback is called, that code gets a final chance to make updates to the DOM, which may accumulate further the needs for painting. If in that callback you also register another callback on RAF, it will not execute at that time, but later: at the next time that the browser will prepare its repaint task -- so not the current one.
Let's say you have this code:
requestAnimationFrame(update);
myElement.style.backgroundColor = "silver"; // This queues a need for repaint
function update() {
// This queues a need for repaint
myElement.style.width = Math.floor(Math.random() * 100) + "px";
requestAnimationFrame(update);
}
When this executes, we get the following sequence:
update
is registered as callbackupdate
before doing anything else.update
function is registered as callback again.update
callback.