-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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: formalize waitForRequestsIdle (experimental) #16135
Conversation
Run & review this pull request in StackBlitz Codeflow. |
Is there a reason we need a builtin API to support this usecase? Couldn't a workaround like this (related #6011) works instead? And until Rollup also supports a standard way for this, we can then implement that too? I know it was discussed in rollup/rollup#4985, but it sounds like the API hasn't been figured out, but the feature request is still relevant. |
We were using setTimeout to wait for the initial scan to complete before generating Tailwind CSS. Now that full builds wait until the bundle stage, dev builds can simply run immediately. This might generate Tailwind CSS twice, generating a FOUC, but will be faster than waiting for the timeout. A [proposed Vite change](vitejs/vite#16135) could address the FOUC and extra build.
That workaround is using Vite internals. This PR gives Vuetify, tailwind, UnoCSS, and others a way to do it without risking a breaking change (I actually was thinking on removing If we get an API in rollup we could also adapt to dev, we can deprecate the API proposed in this PR. We can keep this one as @experimental as a signal that it may be removed in a future major. But at least we give downstream projects a solution for the next major (or majors?). |
Wow so many array duplication and promise created, if everyone do that the performance impact on big codebases could be non negligeable. And maybe I'm missing something, but how does this hack works if two plugins do the same? |
I think the promises and array overhead shouldn't be that bad, specially if you don't hold to the promises like we do in core. The implementation in Vuetify does looks like it could add up quickly though. Your other point is more important for this PR, because this only works if there is a global controller that knows every id that is awaiting. If not, you get locked and both parties will never resolve (or they will have to have a time out to bail out defeating the feature). This is a big reason to include this in core. |
I've tested this with
|
Nice! Thanks for testing the PR 🙏🏼 |
The Vuetify link would be the rough idea of a workaround and I'm sure it could be simplified to be more performant. If multiple plugins do the same, they'll cut off each other because of the timeout, so it won't cause a deadlock. Our implementation also has a fixed timeout so I don't think there's a difference. Also, Vuetify doesn't do this hack anymore, it's something they did in the past but they removed a feature that needed this altogether. So I think this will only be for tailwind and unocss today. If we want to support this API still, I don't mind merging. Just felt like it isn't the right abstraction to solve generic problems, rather a very-specific API to solve a single problem. Maybe renaming it as |
It is different because we are in control of what ids are being awaited. So we have a single central controller that avoids the deadlocks. When you call this function in plugin hooks, you should pass the
And for us in the dependeny prebundler, but we are trying to move away from it too. I agree we should promote moving away from this kind of strategies as much as possible, but for projects like tailwind that is a hard ask at the moment (I don't know if it is even possible).
I renamed the function to |
What I had in mind is that if the number of But anyways, it seems like we'll move forward with it. My concern isn't that we should move away from these strategies though (I also did something like this for my projects), but my main concern was that the API doesn't feel like the right abstraction for the problem (less so now with the rename). |
I think the code looks good. |
Tailwind and UnoCSS creates the needed classes used in the app as it discovers them, and triggers CSS HMR events. When the CSS is loaded the first time, before all the source code has been processed it doesn't have all the content it should. Later on, when the CSS is re-generated, a HMR will populate the CSS with the proper classes and a flash of changed styles will be experienced. The tailwind plugin will solve this by calling
As far as I can see, we can't do that. We need a central store that everyone uses. We are already using this API in the deps optimizer. If someone else prevents a CSS from going through the pipeline, there will be a deadlock. We could avoid awaiting CSS on the optimizer, but then you have the same issue with what vuetify was doing for JS files. I think the key here is that we need a way to ignore all the ids that are awaiting. Here is an equivalent feature request for build time that we needed at one point (now it isn't needed as we are not doing deps optimization during build anymore): Tailwind folks may explore some proposals to implement this feature in rollup in the future, because right now they are hacking their way to be able to wait before generating the CSS file. |
Thanks!
I see. IIUC this only prevent FOUC for CSR apps, right? The CSS file will be stalled and until that request resolves, the entire JS files won't be executed by the browser, and the HTML generation won't happen. If the HTML already exists (for example, when SSR is done), FOUC would still happen. |
Yes, this is for CSR. But IIUC, in the SSR case, a plugin will be able to see all the source included in the HTML so it can already use that to generate the full CSS before the browser requests it. So there will not be FOUC either there. |
Ah, yeah, that's true. I've understood. 👍 |
We were using setTimeout to wait for the initial scan to complete before generating Tailwind CSS. Now that full builds wait until the bundle stage, dev builds can simply run immediately. This might generate Tailwind CSS twice, generating a FOUC, but will be faster than waiting for the timeout. A [proposed Vite change](vitejs/vite#16135) could address the FOUC and extra build.
We were using setTimeout to wait for the initial scan to complete before generating Tailwind CSS. Now that full builds wait until the bundle stage, dev builds can simply run immediately. This might generate Tailwind CSS twice, generating a FOUC, but will be faster than waiting for the timeout. A [proposed Vite change](vitejs/vite#16135) could address the FOUC and extra build.
We were using setTimeout to wait for the initial scan to complete before generating Tailwind CSS. Now that full builds wait until the bundle stage, dev builds can simply run immediately. This might generate Tailwind CSS twice, generating a FOUC, but will be faster than waiting for the timeout. A [proposed Vite change](vitejs/vite#16135) could address the FOUC and extra build.
Very sorry to ping all participants, but I spent about 5 hours debugging vite and found out that this PR introduced a bug for me. After upgrading from v5.2.0-beta.0 to v5.2.0-beta.1 (and all next versions) I got very strange behavior: dev server doesn't respond to several file requests (e.g I have no idea what the code does, but the entry point and cause of the problem is change in Could someone help me debugging this change? Or re-review the changes? Maybe I stumbled upon some rare case? I tried to reproduce the issue in freshly created project, no luck. I have created thread 1220740873273475162 on discord, you could reach me out there, and see screenshot of the problem. Thank you for your attention! diff of my "fix"
|
@ZerdoX-x I reviewed the PR again, and I can't find how it could be causing your issue. Please try to create a minimal reproduction and open a new issue so we can track and fix this problem. Thanks! |
I can confirm that there is an issue. Running git bisect and pnpm link to find which commit causes things to break points to this PR. Works before, doesn't work after. A minimal reproduction has proven quite difficult as we have no idea what is causing it. A simple sveltekit starter app doesn't have this issue. |
@knd775 i have managed to reproduce the issue with inlang's paraglide vite. i'll post it later and ping here |
https://git.sr.ht/~zerdox/paraglide-js-adapter-sveltekit_incompatibility_vite-5.2.0-beta.1 Here you are. I'll open issues in both vite and opral (inlang) repos @knd775 do you use paraglide? could you list vite plugins you use? try to drop them one by one in your project to see the one causing your issue. more info will let us know affected plugins let's move our discussion to the issue linked below |
Description
We discussed with @ArnaudBarre about how to delay processing of generated CSS until all other source code has been processed in tools like UnoCSS and Tailwind. This is needed to avoid a flash of style changes.
This PR proposes a solution by reusing the crawl end finder for static imports we have been using for deps optimization. The issue is similar to discovering all imported dependencies before loading them in the browser to avoid the need of full-reloads.
The crawl end finder was only run on cold start. It has been extracted here out of the deps optimizer and is being always run on startup.
There is a new experimental
server.delayUntilStaticImportsProcessed(id)
function that can be called on theload
hook to delay processing of a certain id