Re: [RequestAnimationFrame] Processing model defined

On Tue, Jul 26, 2011 at 11:04 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 7/27/11 1:23 AM, James Robinson wrote:
>
>> The one point of potential interest or controversy is the expected
>> callback behavior for background tabs.  The processing model I've
>> specified says that callbacks do not fire at all when a document is
>> hidden
>>
>
> I'd like to reiterate that I don't think this is acceptable unless _all_
> web platform animation-related callbacks (SMIL, CSS transitions, CSS
> animations, etc) have that as an acceptable behavior.


I don't think that CSS animation/transition events are really the same thing
here (I'm not familiar with SMIL). In CSS animations/transitions, events are
fired for state transitions such as starting the animation, entering a new
iteration of the animation, and ending the animation.  There is no event
fired for each 'tick' since it's the user agent's responsibility to handle
intermediate frames, not the script's.  requestAnimationFrame is for the
ticks of an imperative animation, not necessarily for the state transitions.

As a concrete example, say I had an animation on my page in response to a
click that took 100ms to complete.  If a user clicked at time T and I was
using CSS animations the event sequence would look something like this:

T + 0ms: click, animationstart event dispatched
(T + 0ms, T + 100ms): no events fired, user agent continually updates the
animated state
T + 100ms: animationend event dispatched

If I wanted to do the same thing with an imperative animation and
requestAnimationFrame it'd look something like this:

T + 0ms: click, click handler registers a requestAnimationFrame callback and
a 100ms setTimeout
T + ~16.7ms: requestAnimationFrame callback, animated state updated, new
requestAnimationFrame callback registered
T + ~33.4ms: requestAnimationFrame callback, animated state updated, new
requestAnimationFrame callback registered
...
T + 100ms: end timer fired, pending requestAnimationFrame callback cancelled


If the user clicked and immediately switched tabs the flow would be:

T + 0ms: click, click handler registers a requestAnimationFrame callback and
a 100ms setTimeout
T + 100ms: end timer fired, pending requestAnimationFrame callback cancelled

In other words it'd be exactly the same, except that no work would be done
for the intermediate frames since if the user wouldn't see it.

If CSS animations/transitions or SMIL were to expose a tick callback then we
should definitely be explicit.  Typically, though, you don't need one with a
declarative animation system.


>
>  We've discussed this a few times on the list before and absent any new
>> data I think that not firing callbacks is a better default behavior for
>> users since it uses the least CPU for background content.
>>
>
> Of course.  But that's not the only consideration here; API and platform
> consistency as well as existing author expectations need to be factored in
> too.
>
>
> We can revisit this if we get any new data, for example if we find evidence
>> of
>> compatibility issues with suppressing the callbacks completely.
>>
>
> We have compatibility issues right now, even with just the backoff behavior
> Firefox has.  For example, sites that use jQuery animations to move things
> off an interval timer go completely haywire if you stick them in a
> background tab for a bit in current Firefox or Chrome, and the effect is
> somewhat worse in Chrome due to the fact that it completely pauses the
> callbacks.  See http://api.jquery.com/animate/**#notes-0<http://api.jquery.com/animate/#notes-0> second
> bullet point -- sites violate the advice of that note all the time; we've
> had at least 3 separate bug reports on Firefox about it so far that I've
> seen.  It's enough of a problem that I've been seriously considering
> switching back from the exponential backoff we do now to some fixed but slow
> heartbeat rate.
>

That's useful information to have.  Can you link to some of these bugs so we
can look in more detail at what the page was doing?  We haven't seen a
similar incidence in Chrome so far, but some of that might be due to the
fact that we also aggressively throttle setTimeout() and setInterval() based
timers in background tabs (to a floor of 1000ms).  There's also something to
be said for author education such as the link you posted.

- James

>
> -Boris
>
>

Received on Wednesday, 27 July 2011 06:44:24 UTC