[🐞] PrefetchServiceWorker throws `insufficient resources` when navigating while prefetching
Which component is affected?
Qwik Runtime
Describe the bug
While the PrefetchServiceWorker prefetches the graph, if you interact/navigate to a new page which triggers another prefetch, the browsers throws errors with insufficient resources.
Please see the below video.
https://github.com/QwikDev/qwik/assets/5979984/b38f056e-8baf-48b8-999d-33a63282dfe8
Reproduction
https://github.com/DustinJSilk/qwik-prefetch-nav-crash
Steps to reproduce
$ ./generate.sh
$ pnpm i
$ pnpm preview
Click on the page link before the graph finishes prefetching and see 404s thrown.
System Info
n/a
Additional Information
No response
How can we solve this issue? @DustinJSilk do you have a possible solution?
I'm not too clued up on the current implementation, but would this not point to an issue where $maxPrefetchRequests$ isn't being respected, which means the dependencies for the linked page are all being fetched with the highest priority?
So the issue here would actually be how the graph is built where all 750 child pages are set as required dependencies for the navigated page to load when they aren't needed yet
Can you test this version in your environment pls? It works fine for me.
I'm still getting the same issue mentioned above.
It seems to exist in reverse order as well in a slightly different way, maybe this will help to identify the problem: When first loading the child page, it doesn't prefetch all the symbols yet. Then, when navigating to the home page it prefetches all the symbols in parallel causing the same error as above. I've attached a video below showing this similar issue.
https://github.com/QwikDev/qwik/assets/5979984/d19f32e5-a89f-4327-a129-89c0363dd000
As I think about it, i wonder if its safe to allow the browser to throw these errors since as long as they eventually recover. We don't know what the limit is per device and don't want to restrict how fast we prefetch if the files are high priority.
So I think the real issue here isn't the fact that the errors are being thrown, they can be ignored, but rather that we're fetching bundles with high priority when they aren't in fact high priority.
In my PR the dependencies have less priority than the "prefetch" bundles. I think we need to limit the requests in parallel
It's similar to #6150 because here is fetching all the pages basically
I was considering opening another issue but this might be related.
In commit 548c7d08ed54ef967ed26db7f6a5f57963596f4f there was a change in how prefetch would trigger which caused this bug (or a very similar one) for us when updating.
Prior to that the onVisible prefetch would only trigger on "mobile" devices (windowInnerWidth < 520), after it would also trigger on "desktop".
Now in my instance we had a dropdown navigation menu that would expand on hover, meaning dragging the mouse over the menu caused all the links to become visible and start prefetching at once, potentially queuing way too many prefetch, and clicking on a link would then be ignored until the prefetch were done.
So had to disable prefetch on the menu for now, but it would be nice to have an option to disable prefetch onVisible in some cases. Alternatively if there is supposed to be a fix in this issue where we either have a max prefetch that would not delay the onClick navigation from occurring, or adding a cancel signal to the prefetch (abort controller?) to immediately stop prefetching if there is a navigation event happening, this would be nice.
BTW the doc here: https://qwik.dev/docs/routing/#link-prefetch does not mention the onVisible prefetching
I would say disabling the prefetch would be the wrong solution. What should happen is that the requests for the link you’re navigating to should be fetched with the highest priority so that it doesn’t need to wait for the rest of the prefetches to complete.
I think what's going on here is the moment a possible interaction is on the page, the new prefetch service worker will start grabbing anything it can in the application and start adding it to the bundle graph, regardless of if there is any possible links to navigate to on the page.
https://github.com/user-attachments/assets/450b1a75-a23e-4117-9b21-6bb9c991ab64
This is a more minimal reproduction, following the same reproduction steps. We create a bunch of routes, and then there is nothing on the page except a click handler and a QRL https://github.com/thejackshelton/prefetching-world-repro
It seems to be a bug in the new service worker implementation. Above I am using incognito mode, to see it do the buffering.
I'll look more into the implementation 🫡
confirmed fixed with #6853
Amazing, looking forward to getting these changes to production soon. Thanks @wmertens
@DustinJSilk now that 1.9 is out, can you please check if it solved the issue?
Thanks!
This looks to be solved now with the reproduction repo. I'll get this added to my app this week to see how it performs. Thanks for getting this done, everyone!