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

<link> rel="modulepreload" #213

Closed
3 of 5 tasks
irori opened this issue Nov 7, 2017 · 21 comments
Closed
3 of 5 tasks

<link> rel="modulepreload" #213

irori opened this issue Nov 7, 2017 · 21 comments
Assignees
Labels
Missing: external bug reports We have issues from the review, but not bugs that belong to this group Progress: pending editor update TAG is waiting for a spec/explainer update Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review Resolution: unsatisfied The TAG does not feel the design meets required quality standards Topic: fetch and preload Things that live on top of (but close to) networking. Topic: scripting ECMA, Web Assembly bindings, etc. Venue: WHATWG

Comments

@irori
Copy link

irori commented Nov 7, 2017

Dear Sirs and Madam of TAG!

I'm requesting a TAG review of:

Further details (optional):

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify: @domenic, @irori
@plinss plinss added this to the tag-telcon-2018-01-02 milestone Dec 5, 2017
@torgo torgo modified the milestones: tag-telcon-2018-01-02, tag-f2f-london-2018-01-31 Jan 16, 2018
@torgo
Copy link
Member

torgo commented Feb 2, 2018

Discussed at London F2F.

@slightlyoff
Copy link
Member

Hey all,

Took this up at this week's F2F in London.

Thanks for filing a design review. We've looked through the design doc and now (relatively old) issues around the design and understand that the design space is highly contended. It looks like all permutations of preload, prefetch, as and type were considered, so there isn't much to discuss. A few points jump out, though:

  • The strongest argument for <link rel="modulepreload"> (vs. regular "preload") is that Modules are expected to be deep graphs, and so lazy fetching behavior needs to be admitted. From traces we've seen, this seems just as true for stylesheets. The lack of symmetry is problematic. We'd like to see an analogue for CSS added that will enable the UA to eagerly and recursively fetch and perhaps pre-process @import'd stylesheets and referenced fonts/images/etc.
  • as noted in some of the source discussion, it's unsatisfying from a layering perspective that there's no way to emulate this behavior from fetch(). Is there still active work on a destination hint?

Overall this looks good and the design seems to be a good compromise in a difficult space. Best of luck with your implementation.

/cc @domenic @annevk @plinss

@slightlyoff slightlyoff added Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review and removed extra time labels Feb 2, 2018
@annevk
Copy link
Member

annevk commented Feb 3, 2018

You can polyfill modulepreload on top of fetch(). I'm not sure fetch() itself should support recursive fetching, that seems like a layering violation of sorts. (Although maybe fetch() should have a way to bypass the "preload cache", once we've properly defined it, as arguably that would be the low-level call.)

whatwg/fetch#486 (comment) addresses to some extent why it wasn't generalized, but I certainly agree with your impression that there's more to explore around the commonalities of CSS and script loading. A somewhat big problem we have today is that the former isn't properly defined.

@slightlyoff
Copy link
Member

So it isn't actually clear that you can polyfill this for CSS. Is it possible to actually get access to all of the bytes for all @import'd resources in a CSS file? What if they're x-origin but not CORS'd? There are likely similar problems for JS.

I agree that fetch() feels weird here, but I'm not sure where else to do this. Perhaps one way to think about it is, instead of an option to fetch(), it could be something we teach Body about?:

let sheet = await fetch("sheet.css");
let deps = await sheet.dependencies(); // an iterable of URLs? IDK.

@triblondon
Copy link

triblondon commented Apr 7, 2018

TAG has been discussing the scope and nomenclature around this. I am wondering whether you considered creating an additional directive, to indicate that preload should additionally explore the dependency graph of the resource, in a similar vein to the includeSubdomains directive of Strict-Transport-Security. This would allow this 'deep-preload' behaviour to be tied specifically to certain media types. We note that the as attribute of Link is a destination as specified in fetch, and a subset of these values represent media types that potentially have a dependency graph (specifically document, script, style and serviceworker).

Example:

Link: </path/to/something>; rel=preload; as=script; includeDependencies
<link rel="preload" href="/path/to/something" as="script" includeDependencies>

@domenic
Copy link
Member

domenic commented Apr 7, 2018

We did indeed explore that. However, as noted in whatwg/fetch#486 (comment), the dependency-crawling is only a small aspect of the overall behavior change that makes using preload a bad fit. Notably, this is not a preload in the network fetching sense, and does not involve the preload cache; it preloads into the module map, which is very different.

@slightlyoff
Copy link
Member

But doesn't it also require that you fetch the resources in order to populate the map correctly? It sounds like that's also not great layering. Maybe they can be separated somehow?

@domenic
Copy link
Member

domenic commented Apr 7, 2018

It depends. Fetching subresources is an optional part of modulepreload, and not the most important part. Populating the module map is the primary goal.

I don't really agree with the value judgments about the layering here, but am not sure how to make that a productive conversation.

@travisleithead
Copy link
Contributor

Bonjour @domenic. Was thinking about https://github.com/domenic/package-name-maps and how modulepreload relates, and wondered what you think the relationship is between the two? Some thoughts below:

  • If you have to list out a set of module URLs to preload, why do both this + a package name map? (Assuming both concepts land)
  • the package name map probably is a superset of the things that might want to be preloaded. Would it makes sense to add the concept of "please preload" to the package name map as well (possibly instead of modulepreload)?
  • clearly the package name map can specify subresources of resources. However, not everything requested by the module graph need be in the package name map. So, from that standpoint, perhaps the use-cases are sufficiently different that the two concepts aren't as synonymous as I thought?

@domenic
Copy link
Member

domenic commented Nov 9, 2018

and wondered what you think the relationship is between the two?

I think they're mostly orthogonal, but I agree it's tempting to stretch package name maps (now renamed import maps) to cover similar cases. In particular:

If you have to list out a set of module URLs to preload, why do both this + a package name map? (Assuming both concepts land)

Import maps are not about loading at all. They're about how to translate certain strings into HTTP(S) URLs.

In particular, the format used for specifying this string -> URL translation cannot be used to derive an exhaustive list of the URLs of all modules in an app. This is for two reasons:

  • Only some strings need translation into URLs. That is, the only URLs that will appear within an import map are those that you want to address by a "bare import specifier", which will be a subset of an application. Roughly speaking, based on our experience with the npm ecosystem, third party libraries are more likely to be addressed in this way, whereas the application code will not be.

  • The translation format has an important shorthand that allows you to map a specifier prefix to a URL prefix, e.g. you could map lodash/ to https://unpkg.com/lodash/. But, a potentially unlimited number of URLs could be derived from this mapping. That is, the import map format just provides a rule, not any concrete instances.

the package name map probably is a superset of the things that might want to be preloaded. Would it makes sense to add the concept of "please preload" to the package name map as well (possibly instead of modulepreload)?

As explained above, it would probably end up being a subset, or perhaps just overlapping.

We could say that, for the subset of modules that appear by explicit URL in the module map, there could be a hint added to the module map to preload them. (Or, browsers may want to do so anyway, without an explicit hint.) But, given that we'd still need modulepreload for other cases, I'd be hesitant to add this. It seems nicer to keep the preloading and string -> URL translation mechanisms separate. Thoughts welcome.

clearly the package name map can specify subresources of resources. However, not everything requested by the module graph need be in the package name map. So, from that standpoint, perhaps the use-cases are sufficiently different that the two concepts aren't as synonymous as I thought?

Exactly :)

@plinss plinss removed this from the 2018-11-13-telcon milestone Nov 13, 2018
@torgo torgo assigned hober, cynthia and dbaron and unassigned travisleithead Feb 5, 2019
@travisleithead travisleithead self-assigned this Feb 5, 2019
@dbaron
Copy link
Member

dbaron commented Feb 5, 2019

We had a brief discussion and will have a breakout later. Some questions that came up:

  • graph traversal more generally (e.g., for @import in CSS, etc.), for preloading, for fetch, etc.
  • surface syntax (distinction between rel=modulepreload vs. rel=preload as=...)
  • fetch options

@bennypowers
Copy link

Hello! I'm a developer that's using modulepreload.

I made a rollup-plugin-modulepreload which injects modulepreload links into the <head>.

I think modulepreload is a great feature and would love to see wider adoption.

(FWIW, from an app developer perspective, I have no preference for either modulepreload orrel="preload" as="module", I just would like to see this shipped.)

Thanks for your consideration.

@dbaron
Copy link
Member

dbaron commented May 22, 2019

@cynthia and I looked at this in a breakout at the TAG face-to-face in Reykjavík.


I think the thing that's bothering us the most is the optionality of the dependency loading. It seems like the spec should either define one behavior or the other rather than allowing implementations to do either. Making it optional means that authors will have to list all their dependencies if they want them to all preload.

It's not clear to me what the argument against loading dependencies is. Is it simply a question of value to developers (and users, for better performance) versus browser implementor convenience? Or is there something deeper that makes the dependency loading complex?

The example shows a very long list of <link rel=modulepreload> elements. This also seems problematic in that it's a barrier to optimization; it's a very long list that's likely to be identically included into many different pages on a site. It will then have to be parsed and processed each time without any benefit of caching, whereas if only the toplevel module includes were modulepreloaded the browser might have more opportunities to remember the preloading work it does for one page to speed up the loading of another page.


From the earlier discussions it seems like there are two future feature requests that we don't need to hold up this review for, but that we should note:

  • recursive fetching for preload of other resource types
  • integration of recursive fetching into fetch or a higher-level fetch-like API

@dbaron dbaron added Progress: pending editor update TAG is waiting for a spec/explainer update Topic: fetch and preload Things that live on top of (but close to) networking. Topic: scripting ECMA, Web Assembly bindings, etc. Venue: WHATWG labels May 22, 2019
@cynthia cynthia added the Missing: external bug reports We have issues from the review, but not bugs that belong to this group label May 22, 2019
@cynthia
Copy link
Member

cynthia commented Jan 13, 2020

@irori @kinu if we were to report the two feature requests noted above somewhere, what would be the best venue?

@dbaron
Copy link
Member

dbaron commented Jan 13, 2020

I filed one of those feature requests as whatwg/html#5208.

I'm now less confident that the second is worth filing. It's not clear to me what sort of results a generic recursive-fetching API would want to return. I think the useful ones build particular data structures (e.g., module graphs, stylesheet objects) and thus aren't generic.

@dbaron
Copy link
Member

dbaron commented Feb 10, 2020

We discussed this on a breakout meeting today and will propose that (in the plenary meeting in 2 days) we close this issue. It's been open a long time. We've provided some feedback (perhaps later than we should have), not much has happened regarding that feedback, and it's not clear whether it's too late for that feedback to be acted upon (although it seems like it's the sort of thing where it likely could be). But it doesn't seem like very much will happen as a result of keeping the issue open, so it's probably time to close it.

@dbaron dbaron closed this as completed Feb 12, 2020
@plinss plinss added the Resolution: unsatisfied The TAG does not feel the design meets required quality standards label Feb 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Missing: external bug reports We have issues from the review, but not bugs that belong to this group Progress: pending editor update TAG is waiting for a spec/explainer update Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review Resolution: unsatisfied The TAG does not feel the design meets required quality standards Topic: fetch and preload Things that live on top of (but close to) networking. Topic: scripting ECMA, Web Assembly bindings, etc. Venue: WHATWG
Projects
None yet
Development

No branches or pull requests