-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Async script output #3163
Comments
Yeah I hit this while working Solid plugin a few weeks back as well. We ended up doing an inline plugin like: {
name: "html-async",
enforce: "post",
transformIndexHtml(html) {
return html.replace('type="module"', 'type="module" async');
}
} But really any library that wants to take advantage of progressive rendering would want this feature so that scripts can start loading and executing before the document is finished streaming in. Without it progressive rendering(streaming) loses its primary benefit. |
IMO, this looks like a clean solution.
If several scripts end up combined in a single one, we could:
I think it would be great to have the PR, so we can later discuss this feat with Evan with the change set on the table. Thanks for the proposal! |
Hello @DylanPiercey. We like your proposal/feedback and would appreciate a contribution via a Pull Request by you or another community member. We thank you in advance for your contribution and are looking forward to reviewing it! |
@DylanPiercey sorry for the delay. We discussed this enhancement with the team and there was a great reception for it. The API as you suggested looks good to avoid the need for non-standard config or markers. And we can use the heuristic I described in my last comment to define if a chunk can be async or it needs to be referred (it can only be async if all the files in the chunk are marked as async modules). |
I’d be happy to work on it but I’ve got several other things on my plate for the moment. Probably won’t be able to put up a PR for a couple weeks. |
Clear and concise description of the problem
Currently Vite outputs
<script type="module">
scripts which are executed in deferred mode. Although this is a lot better than the blocking default of standard<script>
tags, it does have an issue with streaming.Specifically
defer
does not execute any scripts untilDOMContentLoaded
has fired. This means that if you are using SSR + streaming (or even if your document is sufficiently large to be parsed by the browser in multiple segments) that no scripts execute until the browser receives the final byte of html.This is especially bad with streaming + partial hydration, where you are intentionally are sending down sections of interactive html and would like for it to hydrate ASAP. Instead right now in Vite hydration will be blocked until streaming has finished.
Simply adding
async
to these scripts causes them to download asynchronously without blocking the rest of the document (as the name implies) similar todefer
, however it also allows the scripts to execute as soon as they are downloaded.Adding
async
blindly to Vite's output scripts as it stands would cause a race condition for common setups though, since they could be relying on the document being complete by the time initialization code runs, for example:This does not account for the case where the script has downloaded and is ready, but the
#my-app
content has not yet been sent by the server.It would be nice if there was some way to preserve the simple behavior of Vite to support the above without much complexity, while also allowing a way to opt into the
async
style hydration.Suggested solution
One potential option could be to support a special handling of
<script async type="module" src="..."/>
in the.html
files. We could perhaps use this to indicate that the chunk being loaded is capable of initializing immediately. I think this might be a bit tricky though since technically you can have multiple scripts in your.html
file that would get merged into the same chunk and loaded together.Alternative
One not so great option would be to have a dynamic import in the
.html
file like:This is a bit verbose though and currently does not seem to actually work.
A naive compilation of this might also introduce an additional network waterfall, which trades one perf issue with another.
Additional context
I'm not clear on the solution here but wanted to get the discussion started. Happy to create a PR if we can decide on a direction.
The text was updated successfully, but these errors were encountered: