jquery
                                
                                
                                
                                    jquery copied to clipboard
                            
                            
                            
                        Use RAF's timestamp for smoother animations
jQuery 3.0.0-rc1 uses requestAnimationFrame, resulting in significantly smoother animations compared to before. However, its tweening logic uses Date.now() instead of the RAF timestamp argument. As a result, the animation is still slightly choppy.
Before you switch to using timestamp, I should point out that the Velocity.js library opts not to use timestamp (velocity.js:3366):
/* We ignore RAF's high resolution timestamp since it can be significantly offset
   when the browser is
   under high stress; we opt for choppiness over allowing the browser to drop huge
   chunks of frames. */
var timeCurrent = (new Date).getTime();
I don't know if this is actually still an issue in modern browsers. @julianshapiro originally wrote this code in 2014 -- perhaps he can chime in with some details.
I created a test case to demonstrate choppiness resulting from not using timestamp: https://codepen.io/joliss/pen/wWKGeV/ (The test case uses Velocity.js, but I believe it's the same for jQuery.)
My hope is that you can use this test case as a debugging aid, and as a motivating example to convince browser vendors to get any remaining timestamp issues resolved.
Running the CodePen, we see that there is some slight choppiness with the jQuery's getTime implementation:

Using the RAF timestamp argument instead, the animation feels smoother, and the graph is perfectly smooth as well:

I thought that perhaps using the microsecond-resolution performance.now() function would improve smoothness, but it doesn't seem to help much:

A great analysis, thanks a lot! I'm surprised that using performance.now() gives worse results than using the timestamp since it's based on the same timer.
I made a quick patch for jQuery 3.0.0-rc1 that made it use the rAF timestamp: https://gist.github.com/mgol/59155e734d86095f58d505824f7503c2 and added a button for it in your test case: http://codepen.io/mgol/pen/VjvjdL
The graph looks similar to the Velocity using timestamp one.
Note that I'm seeing the performance difference in Chrome 51 but I don't see any gain in Safari (9.1 & TP) and Firefox; Safari mostly looks like your "Velocity plus performance.now" test case in all cases (including the getTime one in which it's better than Chrome), Firefox looks terrible in all cases. I'm not sure if doing sth like that just for Chrome is worth it... :/
EDIT: In Edge 13 all cases look the same, worse than in Safari but way better than in Firefox.
Re Firefox: the terrible graphs that I'm seeing are there only if I use the integrated graphics card in my MacBook. i.e. Intel Iris Pro 1536 MB. If I switch to the dedicated AMD Radeon R9 M370X 2048 MB, it gets closer to Safari. Perhaps Firefox has problems with hardware acceleration for Intel GPUs.
I've always found that dropping a huge chunk of frames upfront is more visually jarring than an FPS hit. In real world (low-stress) animation scenarios, the FPS hit isn't that noticeable — if at all.
@mgol Good point. I created an issue on the Firefox bug tracker: https://bugzilla.mozilla.org/show_bug.cgi?id=1278408 Let's see what they say, and if necessary we can create issues on Edge and Safari too.
@julianshapiro I agree dropping chunks of frames is really bad. Is this still happening though? (Or to be more precise, is it worse for timestamp compared to Date.now()?) Plotting timestamp values with a no-op requestAnimationFrame, I don't see any initial framedrops: https://codepen.io/joliss/pen/ZObOPm
Very cool. Thanks for this.
I also updated the bug with a reference to an older bug on which I added @bzbarsky to take a deeper look.
Nice test!
Judging by the discussion in mozilla thread we still can't use it right? After it will be fixed (fingers crossed), we still should look at older/other browsers that we support?
On Firefox 46 with Windows 10 it looks as smooth as Chrome. As long as we don't make things much worse on Firefox by changing to the rAF timestamp is there anything to stop us from changing it now? To @markelog's point we would also need to ensure it doesn't degrade too much for browsers like Android or IE9.
@dmethvin My quick patch made jQuery.fx.tick accept a timestamp parameter so that'd slightly change the API; to avoid that we'd need a wrapper function which might increase the code size a little.
I just don't see much gain in using the timestamp until it improves the situation only in Chrome. Maybe as a way of preparing for the future? I can prepare a PR to discuss the details further.
Ah, you said it's as smooth as Chrome for you in Firefox on Windows 10. Do you mean it looks like the same graph as the second one from the original @joliss post, completely smooth? That'd change the situation. :)
Yeah, here are my Firefox results, very smooth:
In here @mgol points out that timestamp dependant on graphics card (@dmethvin your card might just be in "good" category), is it not case? The same story could be with other browsers?
This https://bugzilla.mozilla.org/show_bug.cgi?id=1278408#c10 is also disturbing
Also, if we can do this and it is not the issue, why those tickets are open?
In here @mgol points out that timestamp dependant on graphics card (@dmethvin your card might just be in "good" category), is it not case?
Possible. The current data points to the thesis that it's never worse when using the timestamp than when not using it and sometimes it's better.
PR: #3151. Please review.
CC’ing Mozilla folks: @miketaylr @digitarald @bzbarsky @annevk @kentuckyfriedtakahe @cyberdees
Pushing to at least 3.3.0 as Chrome apparently has a bug that makes timestamps arrive to our step function not always in ascending order. See https://github.com/jquery/jquery/pull/3151#issuecomment-285347910 for more details.
This requires more investigation, with issues around out-of-order scheduling in Chrome that I've experienced as well as recent timer throttling due to Spectre. Postponing to 4.0.0.