W3C home > Mailing lists > Public > public-webapps@w3.org > October to December 2010

Re: requestAnimationFrame

From: Gregg Tavares (wrk) <gman@google.com>
Date: Wed, 17 Nov 2010 14:22:33 -0800
Message-ID: <AANLkTimY5tZ6099fsH7-O4k2FmbLMd2Dsj1rjcW1PnWq@mail.gmail.com>
To: robert@ocallahan.org
Cc: Boris Zbarsky <bzbarsky@mit.edu>, "public-webapps@w3.org" <public-webapps@w3.org>
On Wed, Nov 17, 2010 at 10:45 AM, Gregg Tavares (wrk) <gman@google.com>wrote:

> On Tue, Nov 16, 2010 at 12:28 PM, Robert O'Callahan <robert@ocallahan.org>wrote:
>> On Wed, Nov 17, 2010 at 7:52 AM, Gregg Tavares (wrk) <gman@google.com>wrote:
>>> So if the JS on the beforePaint takes a while to complete what happens to
>>> the browser? For example if you are resizing the browser? Is the browser
>>> forced not to be able to actually paint until JS returns?
>> Not necessarily. In Firefox 4, yes. In Mobile Firefox, which supports
>> compositing in a separate process from the content, no.
>>>> Now, when animation is happening on a separate compositor thread that
>>>> guarantee has to be relaxed a bit. But we'll still try to meet it on a
>>>> best-effort basis --- i.e. "we'll run the JS animations once per composited
>>>> frame, if the JS can keep up".
>>> So you're saying that there's no guarantee that requestAnimationFrame
>>> will actually keep things in sync?
>> Right. A cast-iron guarantee that requestAnimationFrame callbacks will run
>> to completion before painting is incompatible with the goal of being able to
>> repaint the browser window even if scripts are running too long or
>> completely hung.
>> But we *can* guarantee that a) scripted animations stay in sync with each
>> other, and b) if the HTML5 event loop is not too busy (e.g., animation
>> scripts take much less time to complete than the interval between composited
>> frames and the content process is otherwise idle), scripted animations will
>> stay in sync with with declarative animations even if the declarative
>> animations are being processed by an off-main-thread compositing framework.
>> (OK, this is a bit speculative since we haven't implemented it yet, but the
>> approach seems straightforward.)
> Just blue skying here but .... It seems like if your goal is to keep
> animations in sync the trigger should be an animation tick, not a repaint.
> In otherwords, you want to give JS a chance to update stuff anytime a CSS
> animation updates stuff. That would separate the issue from "painting". So
> what about an "onAnimation" type of event?
> That would separate this issue of the browser having to wait for JS during
> a paint and still keep things in sync.
Think about this some more..... the point if the previous suggestion is that
updating keeping a JS animation in sync with a CSS animation has nothing to
do with "painting" or rendering. The fact that apparently firefox ties those
2 things together is an artifact of firefox's implementation. It's just has
valid to for example have animation running on 1 thread and rendering on
another. Many console/pc games do this. To keep animations in sync requires
syncing the animation values in the animation thread, not deciding to update
values during rendering.

So, if the goal is to let JS sync with CSS animations, putting the in events
related to painting is the wrong model. Solving that problem particular goal
it would make more sense to add a "cssAnimationTick" event or something.
 Any JS that wants to say in sync would add an event handler

window.addEventHandler('animationTick", updateAnimations, ...);

The handler would get passed a clock similar to how beforePaint works now.

Of course going down that path doesn't solve the issue I'm trying to solve
which could be stated as

*) Don't render from JS unless visible (ie, don't execute expensive 2d or 3d
canvas rendering calls when not visible)

With the caveats of

  a) Make it extremely easy to do the right thing so that few if any sites
making canvas ads or canvas games hog the CPU when not visible.
  b) don't make the browser wait on JavaScript.
  c) don't render more than needed. (ie, don't render 60 frames a second if
you're only changing stuff at 15)

It seems like a 'element.setRenderCallback(func, time)' which works exactly
the same as setInterval but only when that element is visible would solve
both of those issues. If you don't want it on element then make it
window.setRenderCallback(element, func, time).  The problem with a name like
"setRenderCallback" is it seems like it's tied to rendering which is what I
want to avoid which is why setIntervalIfVisible makes more sense. That name
does not imply it has anything to do with rendering.

>> Rob
>> --
>> "Now the Bereans were of more noble character than the Thessalonians, for
>> they received the message with great eagerness and examined the Scriptures
>> every day to see if what Paul said was true." [Acts 17:11]
Received on Wednesday, 17 November 2010 22:23:12 UTC

This archive was generated by hypermail 2.3.1 : Friday, 27 October 2017 07:26:28 UTC