New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 675795 link

Starred by 10 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Bug



Sign in to add a comment

Interop: mismatch in when animations are started between different browsers

Project Member Reported by owe...@chromium.org, Dec 20 2016

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).
 
animation.html
448 bytes View Download
Status: Assigned (was: Untriaged)
Labels: Hotlist-Interop

Comment 3 by shans@chromium.org, Dec 21 2016

Labels: Needs-Bisect
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.

Comment 4 by owe...@chromium.org, Dec 28 2016

Noticed another issue about rAF being fired weirdly, for reference: https://bugs.chromium.org/p/chromium/issues/detail?id=529901
Labels: -Needs-Bisect
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.


Comment 6 by suzyh@chromium.org, Jan 11 2017

Cc: shans@chromium.org
Labels: Update-Quarterly
Owner: ericwilligers@chromium.org
Eric, could this be connected to the issue we were talking about in your test-deflake CL today?
The related issue I mentioned in my test-deflake CL is 679981.

Perhaps also related is 607650.

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?

Comment 9 by owe...@chromium.org, Jan 24 2017

Cc: dk...@chromium.org
[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.

Comment 10 by dk...@chromium.org, Jan 25 2017

Cc: esprehn@chromium.org
+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? 
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.
Owner: ----
Status: Available (was: Assigned)
> could this be connected to the issue we were talking about in your test-deflake CL today?

I think they are unrelated.

Cc: smcgruer@chromium.org
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.
Summary: Interop: mismatch in when animations are started between different browsers (was: rAF fires callbacks before next frame unless something else already called rAF)
Description: Show this description
Cc: yoavweiss@chromium.org

Sign in to add a comment