Re: requestAnimationFrame behavior on display:none iframes

On Fri, Feb 15, 2013 at 2:48 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 2/15/13 1:56 PM, Boris Zbarsky wrote:
>
>> On 2/15/13 1:51 PM, James Robinson wrote:
>>
>>> Sounds like feedback to provide for the PageVisibility specification.
>>>
>>
>> Oh, I did.  It was more or less ignored by the editors under the heading
>> of "keeping things simple", which I suppose is better than things being
>> useful.
>>
>
> Let me be more clear.
>
> The way PageVisibility was done picked a simple-to-specify and
> simple-to-implement and better than nothing but worse than it could be
> definition of "hidden".
>
> I didn't have the energy to fight the stop energy on that topic, because
> it just wasn't that important to me in the end, but I strongly believe that
> requiring requestAnimationFrame to tick in iframes that do not have a CSS
> box is wrong, and I object to the spec requiring that behavior. That does
> mean we can't use the "hidden" definition from PageVisibility, but that's
> what we get for having a poor definition of "hidden" in that
> specification...


I think it's necessary to tick requestAnimationFrame callbacks for hidden
iframes.  Consider these two examples:

1.) Gmail loads up a large portion of its script in an iframe styled to be
0x0.  While this iframe is not display:none, it's hidden for any practical
definition of hidden.  Script loaded into this iframe runs in the same
origin as the rest of the page and it scripts the rest of the page.  The
reason it does this is somewhat historical but it's a way to optimize load
by allowing incremental processing of <script> tags within the iframe and
doesn't seem on its face unreasonable.  The issue is script that runs in
this iframe that says requestAnimationFrame will, unless the JS goes
through some contortions, pick up the global context and thus document of
the iframe and not the containing page.  If animations on hidden iframes
did not tick, script that ran inside this iframe would not be able to
animate parts of the rest of gmail UI.  I think this behavior would be
broken.

2.) Many pages wish to embed multiple instances of a widget from a
third-party origin - for instance "Like" buttons for social networks.  An
inefficient way to do this is to load up many independent iframes all
pointed at a third-party domain that all load and run script to set up the
widget and communication.  techcrunch.com loads up widgets from Facebook,
Twitter, LinkedIn and Google+ next to each story when hovered over.  A more
efficient way to achieve this effect is to load up one hidden iframe
pointed to the third-party domain to load up control logic and then
construct a set of visible empty cross-origin iframes to host each instance
of the widget.  The host page can then postMessage frame IDs to the hidden
control iframe to allow it to populate the visible widgets without needing
to load up redundant data for each instance.  In this situation it's also
quite likely that any animation logic related to the widgets would run in
the global context of the hidden control iframe and not the visible view
iframes.  It might be possible for the author of the widgets to use the
version of requestAnimationFrame on one of the visible iframe's context to
control animations, but even this would be tricky if it uses a centralized
animation system since it would have to somewhat arbitrarily pick an iframe
to bind to.

The common problem here is that the visibility of the document associated
with the global context that requestAnimationFrame is picked up from is a
poor proxy for the visibility of the thing the author is actually trying to
animate.  I think the solution is to provide a better binding between the
intent to animate and the thing being animated so the browser can correctly
optimize these cases.  In hindsight, it might have been better to put
requestAnimationFrame on the document object instead of window since that
might have made the association between context and document a bit more
explicit, but it's possible that wouldn't have helped.

The proposal that has the most promise in this area is associating a DOM
element with the request itself but thus far nobody has stepped up to
specify all the corner cases there.  I'm not sure, for instance, how one
would express the desire to animate something from initially being
display:none or positioned very far offscreen into view.

The definition of "hidden" defers to PageVisibility in order to get the
desired behavior.  This definition could be moved into the
requestAnimationFrame specification if it was useful or if we want to
decouple these specs, but the choice of behavior is deliberate.

- James


>
>
> -Boris
>
>

Received on Wednesday, 10 April 2013 22:33:27 UTC