W3C home > Mailing lists > Public > public-web-perf@w3.org > July 2011

Re: [RequestAnimationFrame] Processing model defined

From: Boris Zbarsky <bzbarsky@MIT.EDU>
Date: Thu, 28 Jul 2011 02:13:21 -0400
Message-ID: <4E30FE01.2020903@mit.edu>
To: James Robinson <jamesr@google.com>
CC: public-web-perf@w3.org
On 7/28/11 1:54 AM, James Robinson wrote:
> In WebKit (that is in Chrome, desktop Safari) animations keep going
> regardless of whether the tab is in the foreground or background.  I
> previously mentioned that Mobile Safari on iOS has (or possibly had) a
> different behavior

Ah, ok.  That was the missing piece, thanks.

>     This doesn't seem to be how sites (and jQuery) are using
>     requestAnimationFrame in practice; instead they're looking at what
>     time it is when the requestAnimationFrame callback is called and
>     just not calling requestAnimationFrame again in their callback if
>     that time is far enough in the future.
> I can believe that a lot of people do that.  That pattern is fine,
> however

As long as you actually get a callback at some point.  If you never do 
because your're in a background tab, until the user switches to your 
tab, then suddenly you do get a callback and your animation runs, which 
is pretty unexpected.

> It's only when the author does want to do something at the animation's
> termination that this becomes an issue.

I believe jQuery does in fact do things from the animation's 
termination, but I haven't sorted through their code in detail.  It may 
be simpler to just ask them....

> Some people writing buggy code and posting on stackoverflow is not the
> same thing as seeing compat issues causing user unhappiness.

Again, this is the most common way I expect people to use this API, 
since it's the way jQuery exposes.  And jQuery-animated transitions 
handling at some interval are a pretty common effect on the web.

The user-facing effect of the jQuery behavior is that when you switch to 
the background tab suddenly however many animations were buffered up 
(figure one per every few seconds that the user was not looking at the 
tab) all run at once, leading to weird bouncing behavior and a pegged 
CPU for a while.

Now maybe we can get jQuery fixed here somehow.  It's not clear to me 
how, since I'm not quite sure what behavior they're _trying_ to implement.

> No new API will every be used correctly by every single author on the web

Yes, but in this case there's a really _easy_ way to use this API 

> There are some real concrete benefits to not firing requestAnimationFrame callbacks at all in
> background tabs

What are those benefits compared to, say, firing them once a minute? 
And yes, I realize that 0 cpu usage is better than "a very small 
amount", but at once a minute we're talking a _very_ small amount.

> and I'd like to try to realize those, even if there are
> a few bumps along the road.

I wouldn't characterize "jQuery's use of the API is broken by design if 
we do this behavior" as a "bump along the road"....  Either the behavior 
of the API needs to change or jQuery's behavior needs to change.  In my 

> It does partially mitigate that particular pattern, however, since the
> page can't enqueue as many requestAnimationFrame callbacks if the
> setInterval() is running at a lower rate.

Well, sure.  But all the code I've seen using this pattern uses an 
interval > 1s anyway, since the idea is to every so often animate 
something on the page and most people don't consider < 1s to be "every 
so often".

> It's a misuse of .animate()

It wasn't until animate() suddenly got changed to use 
requestAnimationFrame.  There was deployed code that was just fine, and 
now it's broken.  That's not OK.

> I don't think we can
> do all that much if a third party library provides an API

Well, we can try to get the third-party library to fix the way it uses 
the APIs we provide, and talk to its authors about how our APIs would be 
easier for them to avoid misusing.

Or put another way, we _do_ want jQuery to build animate() on top of 
requestAnimationFrame and we do _not_ want to break the huge amount of 
deployed content that's using animate() and was perfectly fine with the 
behavior it used to have.  The question is how animate() can implement 
the behavior it used to have on top of requestAnimationFrame.

Received on Thursday, 28 July 2011 06:13:49 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:01:08 UTC