Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Parallel content with iframes of different origins

371 views
Skip to first unread message

David Bruant

unread,
Feb 25, 2013, 2:33:28 PM2/25/13
to dev-...@lists.mozilla.org
Hi,

Servo is new and opens new opportunities, so I'm going to share an idea.
And maybe someone else had it already (I haven't read such a thing yet)
or maybe it's too crazy of an idea, but the discussion may be
interesting anyway.

HTML has <iframe>s. JavaScript can interact with it. There are 2 types
of iframes with 2 different types of interactions:
1) same origin iframes. JS from the parent can mes around with the kid
iframe
2) different-origin iframe. JS from the parent can only interact with it
through message passing via postMessage.
It's also possible via CSS and HTML attributes in the parent to change
the size of the iframe content in the parent page (which is the viewport
size for the iframe, right?) and probably another handful of such style
changes which affect how the iframe is rendered.

It seems like in theory, it could be possible to handle the content of a
cross-origin iframe in a specific Rust task (or bunch of tasks). The few
allowed communications (postMessage, iframe size in the parent, etc.)
would "just" be handled by cross-task communication.

Potential benefits:
* cross-origin iframes are loaded and run in parallel (a bit like
WebWorkers with a UI if you will. So looking forward to transferables
with cross-origin iframes!)
* origin isolation (I feel Rust is already well-equipped for that, but
it doesn't hurt)
* when the iframe@src changes, all the memory that's specific to the
task can be released directly without waiting for GC graph traversals or
refcounting

I've written a small script to be used with scratchpad and the
webconsole [1] and in a 30 minutes look, I've observed some pages with
up to 11 cross-origin iframes in the same page, so it feels like it's
worth a try.
The idea of considering a cross-origin iframe as a WebWorker with a UI
also has some appeal to be honest.


# Addendum: the special same origin iframe@sandbox case

What I've described above only applies to cross-origin iframes. As it
happens, HTML5 introduced a sandbox attribute for iframes [2]. When
applied, the iframe is suddenly put in its own unique origin (regardless
of the origin inferred from its URL). So it could be possible to
consider sandboxed same-origin iframes as parallelizable.
Of course, in JavaScript, the parent of an iframe can, at any time,
remove the sandbox attribute or add the "allow-same-origin" to the
sandbox attribute (IIUC, this value gives back its origin to the content
of an iframe).
I don't know Rust enough to figure out if sandboxed same-origin iframes
can't be parallelized at all or if it's just a very interesting
engineering challenge (bring back to the parent content task the content
of the iframe like if it was never in a different task whenever JS in
the parent decides to ruin the optimization).

Thoughts?

David

[1] https://gist.github.com/DavidBruant/5032258
[2] https://developer.mozilla.org/en-US/docs/HTML/Element/iframe#Attributes

Boris Zbarsky

unread,
Feb 25, 2013, 3:03:08 PM2/25/13
to mozilla-...@lists.mozilla.org
On 2/25/13 2:33 PM, David Bruant wrote:
> 2) different-origin iframe. JS from the parent can only interact with it
> through message passing via postMessage.

Note that whether an iframe is same-origin or not is not time-invariant
across navigations.

> It seems like in theory, it could be possible to handle the content of a
> cross-origin iframe in a specific Rust task (or bunch of tasks). The few
> allowed communications (postMessage, iframe size in the parent, etc.)
> would "just" be handled by cross-task communication.

Yes, as long as you handled navigations possibly moving the iframe to a
new task.

> * when the iframe@src changes, all the memory that's specific to the
> task can be released directly without waiting for GC graph traversals or
> refcounting

That may or may not be true depending on how session history works.

-Boris

Andreas Gal

unread,
Feb 25, 2013, 3:09:51 PM2/25/13
to Boris Zbarsky, mozilla-...@lists.mozilla.org

On Feb 25, 2013, at 9:03 PM, Boris Zbarsky <bzba...@mit.edu> wrote:

> On 2/25/13 2:33 PM, David Bruant wrote:
>> 2) different-origin iframe. JS from the parent can only interact with it
>> through message passing via postMessage.
>
> Note that whether an iframe is same-origin or not is not time-invariant across navigations.

Its also not time-invariant when document.domain is used, correct?

Andreas

>
>> It seems like in theory, it could be possible to handle the content of a
>> cross-origin iframe in a specific Rust task (or bunch of tasks). The few
>> allowed communications (postMessage, iframe size in the parent, etc.)
>> would "just" be handled by cross-task communication.
>
> Yes, as long as you handled navigations possibly moving the iframe to a new task.
>
>> * when the iframe@src changes, all the memory that's specific to the
>> task can be released directly without waiting for GC graph traversals or
>> refcounting
>
> That may or may not be true depending on how session history works.
>
> -Boris
> _______________________________________________
> dev-servo mailing list
> dev-...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-servo

Boris Zbarsky

unread,
Feb 25, 2013, 3:11:26 PM2/25/13
to mozilla-...@lists.mozilla.org
On 2/25/13 3:09 PM, Andreas Gal wrote:
>
> On Feb 25, 2013, at 9:03 PM, Boris Zbarsky <bzba...@mit.edu> wrote:
>
>> On 2/25/13 2:33 PM, David Bruant wrote:
>>> 2) different-origin iframe. JS from the parent can only interact with it
>>> through message passing via postMessage.
>>
>> Note that whether an iframe is same-origin or not is not time-invariant across navigations.
>
> Its also not time-invariant when document.domain is used, correct?

Correct.

Though you can rule this out to some extent if eTLD+1 does not match.

-Boris

David Bruant

unread,
Feb 25, 2013, 4:05:25 PM2/25/13
to Boris Zbarsky, mozilla-...@lists.mozilla.org
Le 25/02/2013 21:03, Boris Zbarsky a écrit :
> On 2/25/13 2:33 PM, David Bruant wrote:
>> 2) different-origin iframe. JS from the parent can only interact with it
>> through message passing via postMessage.
>
> Note that whether an iframe is same-origin or not is not
> time-invariant across navigations.
Whether the same HTMLIframeElement object changes or same-origin-ness
isn't a concern I think, because what would be in a different task would
be the Window instance, not the WindowProxy.
If a given iframe is navigated, as far as the parent is concerned, the
WindowProxy remains the same (per spec anyway) and the underlying Window
is in the same task in the case of same-origin and a dummy stub in the
different-origin case.
In a way, navigation just means "throw away the Window and plug a new
one to the WindowProxy".


Andreas Gal wrote:
> Its also not time-invariant when document.domain is used, correct?
True. I guess the cases of "iframe initially has a different origin than
its parent, but JS can change that" are more numerous than I originally
thought.

>> It seems like in theory, it could be possible to handle the content of a
>> cross-origin iframe in a specific Rust task (or bunch of tasks). The few
>> allowed communications (postMessage, iframe size in the parent, etc.)
>> would "just" be handled by cross-task communication.
>
> Yes, as long as you handled navigations possibly moving the iframe to
> a new task.
As suggested above, the HTMLIframeElement and the WindowProxy would stay
in the parent content task, so no need to move them.
In cases where 2 given documents are time-independently of different
origins, the iframe content would be created in a new task. If
navigation happens, the only thing that changes in the parent is where
communication from the parent is directed to. Maybe it's a new different
task (other cross-origin document), maybe it's in the same task (same
origin document).


For the cases of script-dependent cross-origin-ness (document.domain,
@sandbox="allow-same-origin"), I wonder if it's possible to start in a
new task (optimistically, hoping cross-origin-ness won't change) and
move back the runtime (merging event loops I guess?) to the parent task
when the parent and the iframe end up having the same effective script
origin.
I assume there is no need to move most data because if the parent
content and the iframe content may run in 2 different tasks, they remain
in the same process (so share memory). Only the parallelism needs to be
taken down.
Does it sound doable? reasonable?

>> * when the iframe@src changes, all the memory that's specific to the
>> task can be released directly without waiting for GC graph traversals or
>> refcounting
>
> That may or may not be true depending on how session history works.
In the sense that browsing back may need the data to display the page
more quickly? Or were you thinking of something different?

Thanks for the feedback,

David

Brian Smith

unread,
Feb 25, 2013, 4:51:00 PM2/25/13
to David Bruant, dev-...@lists.mozilla.org
David Bruant wrote:
> It seems like in theory, it could be possible to handle the content
> of a cross-origin iframe in a specific Rust task (or bunch of tasks).

I thought Rust tasks were supposed to be very lightweight. If so, why not put every iframe in a separate task, whether it is same-origin or not?

It would be interesting to get the telemetry to see how common the following kinds of pages are:

1. Page with no iframes
2. Page with only same-origin iframes (and how many such iframes)
3. Page with only cross-origin but same site (eTLD+1) iframes (and how many)
4. Pages with only cross-site iframes (and how many)

> # Addendum: the special same origin iframe@sandbox case
>
> What I've described above only applies to cross-origin iframes. As it
> happens, HTML5 introduced a sandbox attribute for iframes [2]. When
> applied, the iframe is suddenly put in its own unique origin
> (regardless of the origin inferred from its URL). So it could be
> possible to consider sandboxed same-origin iframes as parallelizable.
> Of course, in JavaScript, the parent of an iframe can, at any time,
> remove the sandbox attribute or add the "allow-same-origin" to the
> sandbox attribute (IIUC, this value gives back its origin to the
> content of an iframe).

The iframe sandbox spec says "These flags only take effect when the nested browsing context of the iframe is navigated. Removing them, or removing the entire sandbox attribute, has no effect on an already-loaded page [in the iframe]." So, having the isolation of an iframe depend on the value of the sandbox attribute seems like it would work as well as having it depend on the origin of the iframe.

document.domain is one big reason why it may be most practical to implement such features on a same-site (same eTLD+1) basis instead of same-origin, if there is any reason to treat same-origin and cross-origin iframes differently in terms of task isolation.

Cheers,
Brian

David Bruant

unread,
Feb 25, 2013, 6:54:58 PM2/25/13
to Brian Smith, dev-...@lists.mozilla.org
Le 25/02/2013 22:51, Brian Smith a écrit :
> David Bruant wrote:
>> It seems like in theory, it could be possible to handle the content
>> of a cross-origin iframe in a specific Rust task (or bunch of tasks).
> I thought Rust tasks were supposed to be very lightweight. If so, why not put every iframe in a separate task, whether it is same-origin or not?
Limiting to cross-origin (and my worry for same-origin) isn't about the
weight of a task, but about determinism.
Same-origin page and iframe share the same event loop [1], so I feel it
forces content of both the main page and the iframe (I'm talking about
the code running that manipulates them, not the memory) to live in the
same task and that there is nothing to gain from task isolation. Maybe
I'm narrow-minded because I'm too used to how browsers currently work on
this point? (I would be delighted to learn so :-) )
Are there interesting parallelization opportunities given the event loop
constraint?

As a webdev, I'm particularly excited at the idea that iframes aren't a
performance annoyance and the idea to think of an cross-origin or
sandboxed (thanks to your finding below) iframe as a WebWorker+UI.
Currently, to meet the needs of webdevs, the canvas API is gaining some
ability to be transfered to web workers so that web workers work on them
and transfer the canvas back so that it'd be displayed. I find that
heavy-weight.
If I could create iframe@sandbox and draw there by sending message from
the parent in parallel of doing other things, this transferable canvas
API wouldn't be even necessary.
But if there are substantial gains to just put any iframe in an isolated
task, so be it :-)

> It would be interesting to get the telemetry to see how common the following kinds of pages are:
>
> 1. Page with no iframes
> 2. Page with only same-origin iframes (and how many such iframes)
> 3. Page with only cross-origin but same site (eTLD+1) iframes (and how many)
> 4. Pages with only cross-site iframes (and how many)
I agree these are interesting, but I don't understand why "only". If a
page has 7 cross-origin iframes and 2 same origin, the 7 can be put in
parallel regardless of the 2 others.
So there is something to win even if a page isn't in any of your categories.

I feel the following would be more relevant to the current concern:
* How many cross-origin iframes per page (min/max/mean/median)?
"cross-origin iframe" being only interesting as a measure of parallelism
opportunity.

>> # Addendum: the special same origin iframe@sandbox case
>>
>> What I've described above only applies to cross-origin iframes. As it
>> happens, HTML5 introduced a sandbox attribute for iframes [2]. When
>> applied, the iframe is suddenly put in its own unique origin
>> (regardless of the origin inferred from its URL). So it could be
>> possible to consider sandboxed same-origin iframes as parallelizable.
>> Of course, in JavaScript, the parent of an iframe can, at any time,
>> remove the sandbox attribute or add the "allow-same-origin" to the
>> sandbox attribute (IIUC, this value gives back its origin to the
>> content of an iframe).
> The iframe sandbox spec says "These flags only take effect when the nested browsing context of the iframe is navigated. Removing them, or removing the entire sandbox attribute, has no effect on an already-loaded page [in the iframe]." So, having the isolation of an iframe depend on the value of the sandbox attribute seems like it would work as well as having it depend on the origin of the iframe.
Oh awesome! I had missed the second (out of 3) red warning...
That makes things much simpler than I thought for the @sandbox case.

> document.domain is one big reason why it may be most practical to implement such features on a same-site (same eTLD+1)
As a nit, I came across it on the spec on that, so I'm sharing it here:
it's not exactly same eTLD+1, but rather same Public Suffix List (PSL)
suffix +1 [2].
> basis instead of same-origin, if there is any reason to treat same-origin and cross-origin iframes differently in terms of task isolation.
I'm interested in opinions on task isolation opportunities of
same-origin iframes given the shared event loop constraint, because if
it's possible, the differentiation doesn't make sense.

If not possible and assuming the document.domain trick is rare, I wonder
if the event loop merging idea would work.

David

[1]
http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#groupings-of-browsing-contexts
[2]
http://www.whatwg.org/specs/web-apps/current-work/multipage/origin-0.html#dom-document-domain

Devdatta Akhawe

unread,
Feb 25, 2013, 9:03:08 PM2/25/13
to David Bruant, Boris Zbarsky, mozilla-...@lists.mozilla.org
Hi

First, I think this is a fantastic idea! Thanks David for bringing this up.

>> Its also not time-invariant when document.domain is used, correct?
>
> True. I guess the cases of "iframe initially has a different origin than its
> parent, but JS can change that" are more numerous than I originally thought.

Other than document.domain, what changes effective principal without
navigation? If I am not wrong, document.domain changes would mean that
"if you were a cross-origin frame, but changed document.domain; then
cross-iframe access would be far more slower than if you had started
off being same-origin". I think that's fantastic and should be
considered a feature, not a bug. We want people to stop using
document.domain, right? (postMessage)

http://research.microsoft.com/en-us/um/people/helenw/papers/incoherencyAndWebAnalyzer.pdf
suggests that it was already not common to use document.domain in
2009. It is hopefully less common now and will be even less common by
the time Servo is ready. I just don't think we should consider
document.domain while guiding the design.

Putting iframes from different origins into different tasks might also
help ease moving some critical iframes (like say for *.google.com) to
a new process, which was discussed on this list a fortnight ago.

thanks
Dev

David Bruant

unread,
Feb 26, 2013, 4:16:43 AM2/26/13
to Devdatta Akhawe, Boris Zbarsky, mozilla-...@lists.mozilla.org
Hi Devdatta,

Le 26/02/2013 03:03, Devdatta Akhawe a écrit :
>>> Its also not time-invariant when document.domain is used, correct?
>> True. I guess the cases of "iframe initially has a different origin than its
>> parent, but JS can change that" are more numerous than I originally thought.
> Other than document.domain, what changes effective principal without
> navigation?
I thought changes to @sandbox, but Brian Smith proved me wrong, so I
think that's it.

> If I am not wrong, document.domain changes would mean that
> "if you were a cross-origin frame, but changed document.domain; then
> cross-iframe access would be far more slower than if you had started
> off being same-origin". I think that's fantastic and should be
> considered a feature, not a bug. We want people to stop using
> document.domain, right? (postMessage)
From what I can imagine, the "slower" can come in 2 flavors (or maybe a
mix of the two?):
1) effort to be made to merge the iframe content task into the parent
content task. I feel it's more or less "just" about merging 2 event
loops, but I'm probably missing some parts of the problem (that's partly
why I shared the idea, waiting for feedback on that part)
2) Don't merge, but have the iframe script block on inter-task
communication.

My gut-feeling is that 1) can be manageable (less than a second?) and
it's a cost most pages using the document.domain trick will pay only once.
2) could be more problematic.
Promoting good practices cannot come at the price of making some
existing web pages unusable and if 1) looks cheap enough from a very
high-level point-of-view, 2) looks like it'd be inappropriate.

> http://research.microsoft.com/en-us/um/people/helenw/papers/incoherencyAndWebAnalyzer.pdf
> suggests that it was already not common to use document.domain in
> 2009. It is hopefully less common now and will be even less common by
> the time Servo is ready. I just don't think we should consider
> document.domain while guiding the design.
The paper you're linking to reveals that at the time of study,
1693/89222 crawled websites wrote on document.domain.
window.postMessage was introduced in IE8. We can imagine that websites
relying on the document.domain trick will still exist until IE6 and IE7
die and that's not for today [1] (people posted their IE stats less than
a month ago).
I don't think document.domain can be overlooked if we want Servo to be
eventually used by people.

I'd be interested to see today's numbers.

> Putting iframes from different origins into different tasks might also
> help ease moving some critical iframes (like say for *.google.com) to
> a new process, which was discussed on this list a fortnight ago.
I can't see the post on that. What is so critical about these iframes?
Why the need for a new process? I feel task isolation can be enough.

David

[1]
https://docs.google.com/spreadsheet/ccc?key=0At5NSTamYtYfdGJUSlhBZk1aT0VjaHhrdThkU1hidUE&usp=sharing#gid=0

Boris Zbarsky

unread,
Feb 26, 2013, 9:36:29 AM2/26/13
to mozilla-...@lists.mozilla.org
On 2/25/13 4:51 PM, Brian Smith wrote:
> David Bruant wrote:
>> It seems like in theory, it could be possible to handle the content
>> of a cross-origin iframe in a specific Rust task (or bunch of tasks).
>
> I thought Rust tasks were supposed to be very lightweight. If so, why not put every iframe in a separate task, whether it is same-origin or not?

Because that involves being able to make JS calls directly across tasks.
That's a lot of infrastructure to add.

Furthermore, the web relies on event ordering in same-origin iframes, so
you can't run them in parallel. Serializing multiple tasks is ... hard,
I would assume.

> It would be interesting to get the telemetry to see how common the following kinds of pages are:
>
> 1. Page with no iframes

On today's web, pretty much nonexistent.

> 2. Page with only same-origin iframes (and how many such iframes)

On today's web, I would expect rare, but worth getting telemetry.

> 3. Page with only cross-origin but same site (eTLD+1) iframes (and how many)

Again, I would expect rare.

> 4. Pages with only cross-site iframes (and how many)

I would expect this to be common. For example every single Facebook
Like button or Google+ +1 button involves a cross-site iframe.

-Boris

Boris Zbarsky

unread,
Feb 26, 2013, 9:39:14 AM2/26/13
to mozilla-...@lists.mozilla.org
On 2/25/13 9:03 PM, Devdatta Akhawe wrote:
> Other than document.domain, what changes effective principal without
> navigation?

Nothing.

> If I am not wrong, document.domain changes would mean that
> "if you were a cross-origin frame, but changed document.domain; then
> cross-iframe access would be far more slower than if you had started
> off being same-origin".

That assumes we have a way of proxying arbitrary JS and DOM calls across
task boundaries at all. Is it worth building such infrastructure for
this edge case?

> I just don't think we should consider
> document.domain while guiding the design.

I think we should absolutely consider it in the sense that:

1) We'll need to support it.
2) We want to minimize the amount of work we put into supporting it.

-Boris
0 new messages