Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[worklets] <script> tag import feature design. #376

Closed
bfgeek opened this issue Apr 6, 2017 · 14 comments
Closed

[worklets] <script> tag import feature design. #376

bfgeek opened this issue Apr 6, 2017 · 14 comments

Comments

@bfgeek
Copy link
Contributor

bfgeek commented Apr 6, 2017

From feedback in various forms there was desire to have a declarative way to import scripts initially.

A simple proposal for this would be:

<script type="paintworklet" src="foo.js"></script>
<script type="audioworklet">
registerAudioProcessor(...);
</script>

All other attributes would work as expected, e.g. "async", "defer", "nonce", "integrity" have the same behaviour as modules.

(For "async" in particular it'll spin up a global scope, and import the script before the document has finished parsing).

"crossorigin" would be the special one for the moment, which would be forced to "omit" until we decide if we should have cross-origin support.

@bfgeek
Copy link
Contributor Author

bfgeek commented Apr 6, 2017

cc/ @domenic @annevk thoughts?

@domenic
Copy link
Contributor

domenic commented Apr 7, 2017

This seems bad since it will run the code in the main page context if the browser doesn't support worklet="". To avoid that you'd need a new type (e.g. type="paintworklet" or similar).

I think it might also be better to use <link> for this, as it's linking to an external resource to be registered somewhere, not running script in the main document. That's what service worker did with <link rel="serviceworker">.

@annevk
Copy link
Member

annevk commented Apr 7, 2017

From OP it seems they want to have inline scripts as well. But yeah, rather than a new worklet attribute the easiest seems to just put it all in type. It's nice that worklets are already JavaScript modules so we don't need that extra dimension here.

@bfgeek
Copy link
Contributor Author

bfgeek commented Apr 7, 2017

Yes, inline scripts are desirable if html modules get off the ground again, e.g. if this was used inside the <paper-ripple> web component:

<!-- paper-ripple.html web component file -->
<link rel="import" href="../polymer/polymer.html">
<script type="paintworklet">
  // code specific to the paper-ripple web component...
</script>
<template>
  <div id="foo"></div>
</template>
<script>
   // actual web component code....
</script>

type="paintworklet" makes sense, updated the initial comment to reflect that.

@bfgeek
Copy link
Contributor Author

bfgeek commented Apr 7, 2017

@nyaxt might have thoughts as well.

@domenic
Copy link
Contributor

domenic commented Apr 7, 2017

I think it'd be pretty bad to have inline scripts that run in a different global.

@bfgeek
Copy link
Contributor Author

bfgeek commented Apr 7, 2017

I think it'd be pretty bad to have inline scripts that run in a different global.

Can you explain your reasoning here?

My concern if we don't allow this is that web developers will simply polyfill this themselves, e.g.

<!-- inside the page or web component file -->
<script id="code" type="paintworklet">
  /* some large complex paint worklet code goes here */
</script>
<script>
  const blob = new Blob([document.getElementById('code').textContent]);
  await CSS.paintWorklet.import(URL.createObjectURL(blob));
</script>

Which is bad for performance (duplicates a bunch of memory), etc, hence to provide this natively.

@annevk
Copy link
Member

annevk commented Apr 8, 2017

@domenic really? We've had the exact same requests for workers in the past. Which also still seems fairly reasonable.

@annevk
Copy link
Member

annevk commented Apr 8, 2017

(What @bfgeek sketches above is what I've seen for workers as well. It just hasn't surfaced enough for anyone to start caring.)

@nyaxt
Copy link
Member

nyaxt commented Apr 8, 2017

From implementor + spec reader POV, using <script> element implies that the worklets are going to be a variation of script and scheduled via script processing model.
I share the concern w/ @domenic here that having a script variation that doesn't run in the main world environment may be a bit complicated. I'm also not completely sure what {async,defer} would mean for worklet scripts. @domenic's proposal of using <link> element is much easier to implement in terms of current Blink.

However, from pure mark-up perspective, I can also be convinced that <script> is the most natural way to express any kind of script fragment in the code. Implementing the primitive in Blink isn't technically impossible, but as we are currently actively rationalizing the existing code to actually implement script concept as specified and adding module script concept, it will take some time to deliver.

@domenic
Copy link
Contributor

domenic commented Apr 10, 2017

It just seems very strange to me to have scripts like

<script>
self === window;
document.addEventListener(...);
</script>

<script type="module">
self === window;
document.addEventListener(...);
</script>

<script type="paintworklet">
self === window; // fails, window is undefined
document.addEventListener(...); // fails, document is undefined
</script>

all in the same source document.

Maybe there is no better option; after all the HTML parser makes it very hard to have any new element contain unstructured data like <script> does. But I think it will be surprising for authors and, as @nyaxt expresses, will get in the way of implementations which are so far assuming that <script> has a very specific processing model.

In other words, this seems to be a request to reuse the parser behavior of <script>, but ignore the rest of its processing model, which is confusing.

If this feature is mostly related to HTML modules, then I'd suggest feeding this back into the discussion there, as it may inform the design there (e.g. using a different HTML parser or different format that isn't HTML as the container).

@surma
Copy link
Member

surma commented Apr 14, 2017

I see your point @domenic, and that is indeed weird. From a developer’s perspective all I care about is being able to bundle components into a single file with markup, script, styles, worklets et al. If we can achieve that by feeding that back to HTML modules, then I’m all for that.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Worklets, and agreed to the following resolutions:

RESOLVED: Change preferred import to use <link> over <script>
The full IRC log of that discussion
<eae> Topic: Worklets
<dbaron> Github topic: https://github.com/w3c/css-houdini-drafts/issues/376
<eae> Github topic: https://github.com/w3c/css-houdini-drafts/issues/376
<eae> iank_: This topic is the design of the import. We could use a script tag or a link tag.
<eae> iank_: The script tag basically works as outlined in top comment of issue. Effectively you'd have a new type, i.e. type=paintworklet, always loads as module. Either with a src or inline.
<eae> iank_: The link tag version is basically what service worker does. Dominic outlined the proposal in comment 3 on the issue.
<eae> iank_: There are pros and cons for each.
<eae> iank_: Pro for script tag is that it matches what people do today and works with data urls. The downside is that it is running some code in a different global scope which is new and changes the script process model.
<eae> iank_: It is easier for implementers to implement th elink type but more powerful for authors to use a script tag.
<eae> eae: Optimizing for what is best for web developer has my vote.
<eae> Rossen: No opinions?
<nainar> Same for me
<eae> iank_: I could also defer to TAG on this one
<eae> dbaron: My only thought is that if there is a similarity with service worker it would be nice to use the same functionality with different names rather than have different approaches.
<eae> flackr: Related, the hack with the two instances of a worklet to avoid global state. Clearly not ideal but better than not having a way to discourage state. A way to maybe deal with this would be to have an execution context that cannot store global state. The syntax for loading worklets doesn't allow us to change how they are loaded right now. Would it make
<eae> sense for this to be versioned to possibly allow for another execution context down the line?
<eae> iank_: I think both proposals could handle that.
<dbaron> s/flickr/till/
<till> yes, thanks
<dbaron> s/flackr/till/
* eae thanks!
<eae> iank_: Taking dbarons feedback into account it sounds like the link tag is preferable.
<eae> dbaron: don't know how close this is to service worker
<eae> dino: Closer to service worker than inline so makes sense
<eae> philipwalton: You said in the first comment that there was various sources of feedback. Was any of it about supporting situations with js enabled? Would a link tag work in those cases?
<eae> iank_: Think that is a UA decision
<eae> iank_: If browsers have a preload scanner that could apply to <link tags.
<eae> iank_: With a <script tag and data url the memory cost would be higher, possibly.
<eae> philipwalton: link makes more sense to me.
<eae> Rossen: Sounds like we have consensus around link.
<eae> RESOLVED: Change preferred import to use <link> over <script>

@domenic
Copy link
Contributor

domenic commented Oct 16, 2020

Let's consolidate this and the other related issues into whatwg/html#6073.

@domenic domenic closed this as completed Oct 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants