-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Bundle preloading/prefetching #5158
Conversation
|
let cache = getCache(type); | ||
let bundle = arguments[0]; | ||
|
||
if (cache[bundle]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently caching loaders by the bundle path as the only key.
cb6673c
to
dac7351
Compare
cc the proposal-import-assertions folks, @dandclark @xtuc @littledan @MylesBorins and @jakearchibald, who may have opinions on this 😅 |
Benchmark ResultsKitchen Sink ✅
Timings
Cold Bundles
Cached BundlesNo bundle changes detected. React HackerNews ✅
Timings
Cold Bundles
Cached Bundles
AtlasKit Editor ✅
Timings
Cold Bundles
Cached Bundles
Three.js x4 🚨
Timings
Cold BundlesNo bundles found, this is probably a failed build... Cached BundlesNo bundles found, this is probably a failed build... |
1277591
to
6ef0983
Compare
c9d64d1
to
bfb9879
Compare
41ebf3c
to
50b52d5
Compare
I will have to think about this some more, but to me, at a first glance, it makes sense for this to be neither an assertion not a change in how the module is evaluated (a "with" evaluator attribute). I don't think this feature will make sense to put in browsers as proposed, as it is not statically analyzable, and I guess it doesn't make sense with import statements either (since once you encounter an import statement, you already know that you want to do a fetch). So, personally, I don't have any concerns with this as a tool-only feature at this point, but I will keep thinking on it and get back to you if any issue occurs to me. |
Thanks for the feedback @littledan — much appreciated 😄 With this change, Parcel removes all non-assert properties of the object passed as the second argument to dynamic |
fe91e49
to
4642762
Compare
Thinking about this more, I wonder if transformation/"evaluator" attributes actually could work here--but with some very different syntax. What if it was like a static import statement, where you made a transformation to defer it? Then, this could even be implemented in browsers: import foo from "./foo.mjs" with { load: "prefetch" };
const exports = await foo.get() So instead of using dynamic import, you do a static import that is specified to defer it. Then, the module is evaluated only when get is done. This would make the set of prefetches determined reliably just by parsing, no partial evaluation required--the key property to enable eventual browser alignment. |
4642762
to
be2a540
Compare
Merged this, with an understanding that this is likely unstable and going to evolve. As discussed this morning, let's work with @littledan to draft a proposal at a language level that allows us to further explore this space and iterate on ideas, keeping in mind possible implementations in browsers. |
I agree with @littledan that it would be a transformation/"evaluator" attribute. One other use case for loading was lazy: import foo from "./foo.mjs" with { load: "lazy" }; As opposed to tc39/proposal-import-attributes#99 (comment) i think it suits a |
This implements declarative bundle preloading and prefetching in JavaScript using import attributes[0], which is a Stage 2 JavaScript feature.
Usage:
or
Effect: When a bundle A containing
import(B, {prefetch: true})
is requested (in global mode ascript
tag for A is added to the page), alink
tag withrel="prefetch"
for B is also added to the page at the same time.In the future, we could consider allowing setting the
as
priority ormedia
constraints through these import attributes as well, which would get added as attributes on thelink
tag.Question: Should we prefix or nest these attributes as to not interfere with formalized, standardized keys?
It does so by passing along the attributes object (currently only by statically analyzing pairs that have boolean values) in the dependency's
meta
asimportAttributes
when the dependency is parsed by the JSTransformer.In the JSRuntime, when creating the loader runtime, child bundles are walked to find prefetchable/preloadable resources. Currently the entire bundle group is preloaded, and JS bundles use
script
priority and css bundles usestyle
priority.Notes:
Test Plan:
[0] https://github.com/tc39/proposal-import-assertions