Just to show a little more detail, here's a screenshot that shows that the logic of the while-loop version of my animation loop fires inside each animation frame. I've zoomed out and we can see there's nothing fired between the frames:
https://cloud.githubusercontent.com/assets/297678/14764323/c28e83cc-0968-11e6-8771-8e726158aa52.png On Sat, Apr 23, 2016 at 3:18 PM, /#!/JoePea <j...@trusktr.io> wrote: > Alright, I did an experiment, and I'm really surprised at the results! > Apparently, the logic (what would be drawSomething() in my previous > example) is fired within the frame!! > > So, let me show you my original method for starting an animation loop. > I'm working on a 3D project at http://infamous.io. The Scene class > (https://github.com/infamous/infamous/blob/master/src/motor/Scene.js) > has a method for starting an animation loop the standard way: > > ```js > async _startAnimationLoopWhenMounted() { > this._animationLoopStarted = true > > if (!this._mounted) await this.mountPromise > > // So now we can render after the scene is mounted. > const loop = timestamp => { > this._inFrame = true > > this._runRenderTasks(timestamp) > this._renderNodes(timestamp) > > // If any tasks are left to run, continue the animation loop. > if (this._allRenderTasks.length) > this._rAF = requestAnimationFrame(loop) > else { > this._rAF = null > this._animationLoopStarted = false > } > > this._inFrame = false > } > > this._rAF = requestAnimationFrame(loop) > } > ``` > > Here's what the Chrome timeline shows for the logic that is fired > inside the loop: > https://cloud.githubusercontent.com/assets/297678/14764236/8eb72d4a-0965-11e6-9bb9-5db02cc23520.png > > Now, I went ahead and modified my Scene class so the method now looks like > this: > > ```js > function animationFrame() { > let resolve = null > const promise = new Promise(r => resolve = r) > window.requestAnimationFrame(resolve) > return promise > } > > // ... > > async _startAnimationLoopWhenMounted() { > this._animationLoopStarted = true > > if (!this._mounted) await this.mountPromise > > this._rAF = true > let timestamp = null > while (this._rAF) { > timestamp = await animationFrame() > this._inFrame = true > > this._runRenderTasks(timestamp) > this._renderNodes(timestamp) > > // If any tasks are left to run, continue the animation loop. > if (!this._allRenderTasks.length) { > this._rAF = null > this._animationLoopStarted = false > } > > this._inFrame = false > } > } > ``` > > And the timeline results are surprising! As you can see in the > following screenshot, all of the logic happens within the frame > (though you can see there's extra overhead from what I assume are the > extra function calls due to the fact that I'm using Facebook > Regenerator for the async functions): > https://cloud.githubusercontent.com/assets/297678/14764237/8eb71ce2-0965-11e6-942a-3c556c48b9a0.png > > Near the bottom right of the screen shot, you can see the tooltip as > I'm hovering on the call to `animationFrame` which returns the promise > that I am awaiting in the loop. > > Although this behavior seems to be exactly what I was hoping for, it > seems like there is something wrong. Could there be a bug in > regenerator that is failing to defer my loop code to a following tick? > Or is my code deferred to a following tick that somehow the animation > frame knows to execute within the same tick? Maybe there's something > I'm missing about the Promise API that allows for .then() of a promise > (which I assume is what Regenerator is using) to be executed in the > same tick? What's going on here? > > I was expecting to see the code of my loop execute outside of the > "Animation Frame Fired" section. > > On Sat, Apr 23, 2016 at 6:28 AM, Boris Zbarsky <bzbar...@mit.edu> wrote: >> On 4/23/16 4:09 AM, Salvador de la Puente González wrote: >>> >>> AFAIK, that should execute `drawSomething()` once per frame. Given a >>> frame is each time the animatinFrame() promise resolves. >> >> >> What's not obvious to me is whether it will execute it before the actual >> paint for the frame (i.e. before or right after the loop that's notifying >> the animation frame callbacks completes) or whether it will do >> drawSomething() after the paint... >> >> -Boris >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss