Re: [AnimationRequestFrame] Initial editor's draft of AnimationRequestFrame spec available

On Mon, May 2, 2011 at 7:15 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 5/2/11 10:06 PM, Jonas Sicking wrote:
>
>> On the other hand, if you do want to implement the feature James is
>> talking about here, you'd end up with:
>>
>> 1)  Resample declarative animations.
>> 2)  Run animation frame callbacks if any.
>> 3)  Process pending restyles, if any.
>> 4)  Do relayout, if needed.
>> 5)  If something with an animationcallback has been moved into the
>> screen, goto 2.
>>
>
> Not quite, because if we require that things that are not in the viewport
> NOT have their animation frame callbacks called and that animation frame
> callbacks are called in order they were set up, then we need to do relayout
> before running animation frame callbacks for anything with an element
> attached in step 2.  In other words, the algorithm would then need to look
> like this:
>
> 1)  Resample declarative animations.
> 2)  While (have animation frame callbacks that might need to run)
>   I) If next callback has element, flush style and layout
>  II) Run next callback
> 3)  Process restyles.
> 4)  Do relayout.
>
> or something.  I would really like to avoid this situation.


That's pretty much exactly what the implementation in WebKit currently does,
except that the algorithm operates on a copy of the callback list generated
before step 2.  In WebKit, style and layout are lazy and ensure they are up
to date when nothing has changed is very cheap.  This means if the callbacks
are 'well-behaved' and do not manipulate styles or layout unnecessarily then
the work required by steps 3+4 should be minimal.  A callback that does
nothing but issue draws targetting a canvas element, for example, should not
dirty any style or layout information and so steps 3+4 would just involve
checking a few dirty bits in WebKit.  Animation callbacks that cause style
recalculations or layout to take significant amounts of time are going to be
expensive no matter what algorithm we use.

One use case motivating this algorithm is that a page may have multiple
animations active at the same time that interact with each other, for
example the contents of a canvas might be animated by one callback while the
canvas itself or some ancestor is moved by another callback.  In that case I
want to ensure that the canvas contents are always updated when the canvas
becomes visible regardless of what order the callbacks are registered in. To
put it another way, at the end of the invoke callbacks algorithm there
should be no callbacks in the animation frame request callback list that are
eligible to run.

Since the WebKit implementation copies the list of potential callbacks
before invoking any of them, all callbacks registered during the invoke
callbacks algorithm are for the next frame and so it is not possible to
trigger more than N+1 reflows if there are N callbacks registered at the
start of the algorithm.

>
> Another open question is what happens to unfired callbacks.  Do they just
get left in the list, or what?  Consider a single canvas outside the
viewport; in an ideal world we'd be able to do nothing with it until it goes
into the viewport (as opposed to waking up every 16.7ms to check whether it
might be  inside the viewport now).  That seems like it imposes a burden on
the author, though...
>

In our implementation callbacks that are unfired due to element visibility
checks are left in the list for next frame.  In the case of a single
animated canvas outside the viewport Chrome will wake up every ~16.7ms,
update layout (which is cheap if nothing has changed, remember), check that
the element is still not visible, and then do nothing.  Ideally we would not
do anything until the element became visible but in general I don't think
this is feasible.  In any case, doing the visibility check in the browser is
definitely cheaper than calling into the JavaScript engine and having the
script do its own visibility check (which most authors will not do at all).

I'm not sure how an author would do better - there is no reasonable way to
receive a notification when an element becomes visible that does not involve
polling or registering for a large amount of events.

- James

Received on Tuesday, 3 May 2011 05:31:32 UTC