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

fix: under-prefetching — bundle graph missing dynamic dependencies #7417

Merged
merged 5 commits into from
Mar 25, 2025

Conversation

maiieul
Copy link
Contributor

@maiieul maiieul commented Mar 13, 2025

What is it?

  • Bug

Description

Repro: https://github.com/maiieul/qwik-under-prefetching-repro -> TLDR: open.value && <Comp /> has always led to under-prefetching. This could be worked around (as was the case on the qwik.dev docs) by using qwikVite's entryStrategy.manual (https://qwik.dev/docs/guides/bundle/).

I managed to get a pretty good result by checking for each bundle if their dynamic dependencies are entries, reducing the under-prefetching a lot. Then I noticed that removing manualChunks logic on top of that completely gets rid of it with the qwik-city ServiceWorkerRegister. The qwik PrefetchServiceWorker also works but is a bit buggy.



Results https://github.com/QwikDev/qwik/pull/7417:


  • On qwik UI, with the qwik PrefetchServiceWorker there is a bit of over-prefetching (but that’s due to specific PrefetchServiceWorker bugs): ~6s TTI. With the qwik-city ServiceWorkerRegister it is ~2s TTI so ~3x faster. Without the change, it is ~1.5s, but with under-prefetching.

  • There is zero under-prefetching.
  • Since I removed manualChunks, there are less chunks outputted overall, which means the interactions feel snappier. For example the qwik.dev docs search now takes ~50ms to serve all the chunks from SW instead of ~300ms.





Remaining issues/questions:

  • The qwik PrefetchServiceWorker doesn't prioritize the chunks on user interaction. This means if all the chunks need 5s to be prefetched, the app won’t be interactive before that point, and also that the user must re-interact to actually get a result.

  • Both service workers can't prioritize chunks need for user interaction before DOMContentLoaded. For the qwik-city service worker for example, it can start to prefetch chunks before DOMContentLoaded, but cannot re-prioritize. This would be a good optimization to have for 3G networks.
  • There is now a bit more of over-prefetching due to the static imports being wrong. For example copy-icon component on qwik UI statically imports the toggle-group.js, which dynamically imports all of the toogle-group chunks. So instead of over-prefetching only the toggle-group.js, we now over-prefetch all the chunks that come with it :/. I’m hopeful we can find a way to fix this. Probably a setting in rollup.

  • It is unclear to me whether clearTransitiveDeps and the direct <dynamic> check do anything useful. They don’t seem to change anything on qwik.dev and qwik-ui.com I’m concerned these might lead to under-prefetching in some untested situations.

Bonus: this also fixes the docs search 🥳

Malus: I disabled qwik insights because it was logging lots of error on the network tab 🤔

Fixes #4149

list of PRs that created problems with prefetching:

Checklist

  • My code follows the developer guidelines of this project
  • I performed a self-review of my own code
  • I added a changeset with pnpm change
  • I made corresponding changes to the Qwik docs
  • I added new tests to cover the fix / functionality

@maiieul maiieul requested review from a team as code owners March 13, 2025 11:31
Copy link

changeset-bot bot commented Mar 13, 2025

🦋 Changeset detected

Latest commit: 81b3c3b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@builder.io/qwik Patch
eslint-plugin-qwik Patch
@builder.io/qwik-city Patch
create-qwik Patch

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

@maiieul maiieul marked this pull request as draft March 13, 2025 11:33
Copy link

pkg-pr-new bot commented Mar 13, 2025

Open in Stackblitz

npm i https://pkg.pr.new/@builder.io/qwik@7417
npm i https://pkg.pr.new/@builder.io/qwik-city@7417
npm i https://pkg.pr.new/eslint-plugin-qwik@7417
npm i https://pkg.pr.new/create-qwik@7417

commit: 81b3c3b

Copy link
Contributor

github-actions bot commented Mar 13, 2025

built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview 81b3c3b

@wmertens
Copy link
Member

@maiieul I think you can add the isPlan and we can merge this already as a bit of an improvement?

@maiieul
Copy link
Contributor Author

maiieul commented Mar 14, 2025

Yup, I think it's actually quite a big improvement. Without isEntry we were missing a lot of direct level 0 dynamic imports. This also happens to fix the docs search slowness btw 🥹

@maiieul maiieul changed the title fix(vite plugin): add dynamic dependency if isEntry fix(optimizer): under-prefetching — bundle graph missing many dynamic dependencies Mar 14, 2025
@maiieul maiieul force-pushed the fix-under-prefetching branch 2 times, most recently from 530c02a to 411dd87 Compare March 15, 2025 15:50
@maiieul maiieul changed the title fix(optimizer): under-prefetching — bundle graph missing many dynamic dependencies fix(optimizer): under-prefetching — bundle graph missing dynamic dependencies Mar 16, 2025
@maiieul maiieul marked this pull request as ready for review March 16, 2025 16:52
@maiieul maiieul changed the title fix(optimizer): under-prefetching — bundle graph missing dynamic dependencies fix: under-prefetching — bundle graph missing dynamic dependencies Mar 16, 2025
@maiieul maiieul marked this pull request as draft March 16, 2025 19:18
@maiieul maiieul marked this pull request as ready for review March 16, 2025 21:10
@maiieul maiieul marked this pull request as draft March 22, 2025 13:41
@maiieul maiieul force-pushed the fix-under-prefetching branch from ace867c to 9c97fc7 Compare March 22, 2025 13:52
@maiieul maiieul force-pushed the fix-under-prefetching branch from 9c97fc7 to 4e44b4f Compare March 25, 2025 00:09
@maiieul maiieul self-assigned this Mar 25, 2025
@maiieul maiieul force-pushed the fix-under-prefetching branch from 4e44b4f to a339d69 Compare March 25, 2025 00:13
@maiieul maiieul marked this pull request as ready for review March 25, 2025 00:21
Copy link
Member

@wmertens wmertens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs a little cleanup but I think we can merge this even though #7453 will follow soon

@maiieul
Copy link
Contributor Author

maiieul commented Mar 25, 2025

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.

@maiieul maiieul force-pushed the fix-under-prefetching branch from 68dc99a to 0580036 Compare March 25, 2025 11:55
@maiieul maiieul force-pushed the fix-under-prefetching branch from 0580036 to 81b3c3b Compare March 25, 2025 12:11
@maiieul maiieul mentioned this pull request Mar 25, 2025
8 tasks
@wmertens wmertens merged commit 7f12634 into QwikDev:main Mar 25, 2025
19 checks passed
@github-actions github-actions bot mentioned this pull request Mar 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[🐞] Qwik fails to prefetch leading to input delay
3 participants