WebReflection / coincident

An Atomics based Proxy to simplify, and synchronize, Worker related tasks.
MIT License
202 stars 3 forks source link

Using an iframe as coincident's context #38

Closed jed closed 6 months ago

jed commented 6 months ago

I'm attempting to use an iframe with coincident, like this:

index.html

<!DOCTYPE html>
<body>
<script type="module">
  import coincident from 'https://unpkg.com/coincident/window';

  let iframe = document.createElement('iframe');
  iframe.src = './iframe.html';
  document.body.appendChild(iframe);

  coincident(iframe.contentWindow);
</script>

iframe.html

<!DOCTYPE html>
<body>
<script type="module">
  import coincident from 'https://unpkg.com/coincident/window';

  const {proxy, window, isWindowProxy} = coincident(self);

  const {document} = window;
</script>

but get the error Uncaught TypeError: Illegal invocation when trying to access document in iframe.html... any chance there's another way to use coincident with iframes?

WebReflection commented 6 months ago

Hi Jed, the issue is that on the main thread you don't get to use Atomics or SharedArrayBuffer in a way that Atomics.wait makes sense, as it's forbidden to block the main thread with Atomics and I think that applies to iframes too.

this is out of my gut though, I need to investigate what's going on behind the scene but I think you're playing main VS another main by using iframes instead of workers and here my question: why do you need an iframe there using this module, when you have parent access from there to do, when authorized, anything you like and vice-versa?

jed commented 6 months ago

i'm working on a use case that needs off-main-thread DOM operations, so was looking to use a cross-origin iframe for that, which isn't reflected in this repro. is there another approach that you think would work? or would it be possible to instantiate via a MessageChannel or something?

WebReflection commented 6 months ago

you can reflect the current DOM in a worker via LinkeDOM or uhtml/dom modules ... you pass the document.body.outerHTML to that worker, you parse it as document, you then have ability to perform most common DOM operations.

This is the first/quick answer that comes to mind, but while that dance won't be blocking, it would be probably a tad slow on bootstrap ... iframes are not famous for speed neither, so maybe a worker with any of those modules in would be a solution? For LinkeDOM there is an explicit linkedom/worker export, if that helps.

jed commented 6 months ago

interesting, that's a good point. why do you think the bootstrap would be slow for this use case?

WebReflection commented 6 months ago

it's a worker that receives a potentially huge HTML to parse and create the tree but I don't have data to support my claim so ... give it a try?

btw, about this:

i'm working on a use case that needs off-main-thread DOM operations

we use Python in WASM to deal directly with the live DOM from workers and even uhtml works well there ... when you say off-main-thread DOM operations what do you mean?

In any case, with coincident/window you have full DOM access from the worker so you can just grab the window.document or query any part of it, work only on that, apply results after your off-main-thread operations.

If these should not bother the live DOM while operating, LinkeDOM or uhtml/dom would be enough, otherwise you can just do stuff in there and be sure it will be reflected on the main.

In short, I am not sure I fully understand what you need to do or how perfwould be affected, but I would start simple, with a worker, see where you go ... then if you need a parallel DOM for real off-main-thread things you can pick LinkeDOM or uhtml/dom and call it a day.

jed commented 6 months ago

awesome, thanks for the perspective, i'm going to give it a spin. i love the stack you've built here, such a unique and refreshing approach.