-
Notifications
You must be signed in to change notification settings - Fork 1.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
feat: dynamic modulepreload #7453
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 392921d The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
b4e3856
to
5c623f5
Compare
commit: |
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|
Is it a good idea to move fetching bundle graph to the head element? |
The bundlegraph is not that important for initial interactivity, it's better that the browser spends resources on showing the page first. All the entry points get higher priority, so they will be available when you click. |
5c623f5
to
361e497
Compare
const internalDynamicImports = bundle.dynamicImports?.filter((d) => graph[d]) || []; | ||
// If we have a lot of dynamic imports, we don't know which ones are needed, so we don't add any | ||
// This can happen with registry bundles like for routing | ||
if (internalDynamicImports.length > 0 && internalDynamicImports.length < 10) { |
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.
We need to keep the deps.hasSymbols
logic as explained in #7417 (comment)
Ok, in #7453 I just removed all of it and only disallow more than 10 dynamic deps because we're probably not going to guess right. That works fine too it seems.
We need the hasSymbols guard, otherwise we will prefetch external dynamic deps again (e.g. shiki). 10 sounds like a reasonable safeguard, but I wonder if it's needed at all. The dynamic deps graph seems to stop on its own after a certain number of nodes. There is still a bit of over-prefetching on qwik-ui but I'm quite sure it's because some static deps that have dynamic deps aren't being tree-shaken somehow.
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.
but then we won't preload dynamic imports for library components :-/
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.
Hmmm are you sure? I will need to test this. Shouldn't be an issue if libraries use preserveModules
, but better to support both ofc.
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.
I have a better solution now! You can adjust the graph in your vite config now, and I already use it to clear the dynamic imports from qwik-city.
I think preloading shiki or threejs or whatever is good if it is actually needed, so in case it's problematic the dev can optimize manually. See the bundle-graph.unit tests.
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.
I think preloading shiki or threejs or similarly "big" libs can be tricky. We can provide a way to preload those, but it should be optional imo. Otherwise that's also a breaking change.
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.
So I think we need to exclude external deps by default.
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.
How about a setting for maximum preload size?
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.
Might not be needed at all?
bdea31c
to
5d5c54a
Compare
ee1de36
to
23d530b
Compare
8df1c60
to
74b0661
Compare
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.
👏👏👏@wmertens
05d51f1
to
115cee1
Compare
f54c44d
to
a0906bf
Compare
preload doesn't preparse the JS but it is supported by very old iOS devices
this applies to `pnpm serve`, because normally dev mode doesn't generate preload urls
If the dev wants to include other dynamic imports, they can just make a qrl()
temporary until PR gets merged
a0906bf
to
bd69859
Compare
This moves the service worker logic into the qrl handling, adding modulepreload link tags to request preloading chunks that will probably be needed soon.
This allows the browser to do its thing way better, and reduces complexity. (it would also allow some preloading in dev, but only for the SSR result, not implemented)
You can easily test the impact by going to the docs site and clicking the search button.
TODO:
qwik add service-worker
now that the starter no longer includes it