Interop: mismatch in when animations are started between different browsers |
||||||||||||
Issue description(smcgruer@ note: the attached test-case is still valid, but see comment #10 and below for clarification on what the actual issue is here) [assigning to shane for triage] I understand rAF is supposed to queue callbacks to be executed on the *next frame* but our current implementation queues rAF callbacks to be fired in the current frame, except in the case where some other code has already called rAF within this frame in which case it runs in the next frame. Note that Edge implements it as I would have expected, while Blink and Webkit don't. Additionally note that the time recorded by the rAF callback doesn't match the spec as it is supposed to be performance.now() when the callbacks are called, not the time for the start of the frame. A simple repro is attached (see console). All of the above causes issues with animations. For example setting up some CSS transition by toggling a class, calling requestAnimationFrame and performing thread blocking work in the callback blocks the transition from starting. I would expect this animation to work fine as rAF should cause us to wait for the next frame. Instead a double rAF must be used to wait for the next frame (unless some other code on the page happened to already call rAF in this frame, in which case a single rAF is sufficient).
,
Dec 20 2016
,
Dec 21 2016
https://jsfiddle.net/y4s6ozvf/ provides an online repro. The red box should animate immediately when clicked, but on Chrome pauses for 3 seconds before animating. This example works correctly on Edge but incorrectly everywhere else. I'm curious whether this is a regression in Chrome or if we've always had this behavior.
,
Dec 28 2016
Noticed another issue about rAF being fired weirdly, for reference: https://bugs.chromium.org/p/chromium/issues/detail?id=529901
,
Dec 29 2016
Able to reproduce the issue on windows-7, Mac-10.12.2 and Linux-Ubuntu-14.04 using chrome version 55.0.2883.87 and canary 57.0.2965.0 with the URL https://jsfiddle.net/y4s6ozvf/. Oberved that the red box was not animated immediately after clicked. This is non regression as the issue seen from M46 builds. From M30 to M45 not observed the animation. Removing the bisect label.
,
Jan 11 2017
Eric, could this be connected to the issue we were talking about in your test-deflake CL today?
,
Jan 23 2017
The related issue I mentioned in my test-deflake CL is 679981. Perhaps also related is 607650.
,
Jan 24 2017
Could this be an issues of Edge? I mean all Firefox/WebKit/Blink have the same behavior. What exactly spec says about it and why 3 major vendors potentially not following it?
,
Jan 24 2017
[cc dknox for a key predictability issue] Good question. Referring to the specs (https://html.spec.whatwg.org/multipage/webappapis.html#animation-frames and https://www.w3.org/TR/animation-timing/#dfn-animation-frame-request-callback-list so far as I'm aware), there are definitely issues (ordered least significant to most): 1. Chrome and WebKit do not return Performance.now as the time when calling the callbacks, but rather return the time from the start of the frame. This is contrary to "For each entry in callbacks, in order: invoke the callback, passing now as the only argument" and "Let time be the result of invoking the now method of the Performance interface within this context." 2. Chrome only calls a single queued rAF callback per frame. Calling rAF multiple times (not nested) results in the callbacks running on distinct frames. This is contrary to "For each entry callback in list, in order: [...] Call callback with the callback's context's time as the argument." 3. The spec is under specific about when to run the sample animations phase. whatwg says “When the user agent is to run the animation frame callbacks”, while the older source says "user agent MUST regularly queue a task". Neither of these clarify whether a callback passed to rAF within one frame will apply in this frame or next (this would depend on whether the task is scheduled before or after script is allowed to run I guess). 3 results in Edge and WebKit/Blink having different behavior, a key predictability problem causing real world perf issues. A primary use case of rAF is to wait a frame, and I believe many developers are using rAF when they want rAF rAF, due to Chrome's implementation of the vague spec. I'm not an expert in this spec, but personally I wouldn’t be surprised that if we decided to clarify this spec, the logical way to clarify it would be to require the task to be scheduled such that when a callback is queued with rAF it will be called on the next frame.
,
Jan 25 2017
+esprehn Elliott and I chatted about this and I think there's a bit of a misunderstanding of the issue here. Chrome calls all rAF callbacks once per frame. Calling rAF in other locations shouldn't affect when your rAF call runs. Do you have a repro where calling rAF in one location delays the callback for rAF in another location? The reason that animations are delayed here is because the animation can't start until after the synchronous work in the rAF handler (animations are started at the end of rAF before paint commit). Calling a second rAF and putting your expensive code there fixes the problem because it allows the first rAF to finish immediately after queueing the animation. I think the larger issue is that animation start timing perhaps isn't well spec'ed and Edge/Chrome implement differently?
,
Jan 25 2017
Agreed, Dru. I definitely wasn't exactly correct about 2) in comment 9. Chrome does call multiple queued rAF callbacks per frame generally, but I recall that when Shane and I looked into this in Sydney we made a little page that demonstrated that calling rAF elsewhere on the page in the same frame caused our rAF scheduled in response to a touch to be pushed to the next frame, although I don't still have a copy of that and would have to pass over to Shane for the details. Also, agreed that the larger issue here isn't whether or not rAF callbacks get called in the current frame or the next one, but the fact that browsers have different behavior, likely because the spec isn't precise. And it just so happens that our behavior is misunderstood by many developers that think they can use rAF to ensure animations have started, when double rAF is required.
,
Jun 28 2017
> could this be connected to the issue we were talking about in your test-deflake CL today? I think they are unrelated.
,
Mar 29 2018
Based on testing http://output.jsbin.com/godibit across the various browsers, I came to the following conclusions: Waits for 3 seconds before starting: * Chrome stable, dev, canary * Firefox stable, nightly Immediately starts without waiting: * Edge * Safari (I got one report from a colleague of Safari tech preview waiting before starting, but we were unable to reproduce). The next step will be to examine the various animations spec and the rAF spec to confirm whether #9 is still accurate, figure out which behavior is 'correct' by the spec, and either open a spec issue or just have bugs against the appropriate browsers.
,
Mar 29 2018
,
Mar 29 2018
,
Nov 30
|
||||||||||||
►
Sign in to add a comment |
||||||||||||
Comment 1 by andymutton@chromium.org
, Dec 20 2016