-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Description
Describe the bug
I'm just forming the discussion started at #9761 (comment) in a hopefully well formed issue.
This issue is somewhere between a bug and a feature, the best way to see this is as "behavior that was fine and now was stopped working"(after PR #9761).
Problem
Since PR #9761, client side navigation on legacy mode is problematic.
For example, assume hypothetically you have a Nuxt website with the pages "/"(homepage) and "/about", each of them having some CSS.
The user may start in the page "/" and then navigate(**in the client side) to the page "/about", or the opposite, each of the option should be totally valid.
According to Vite, AFAIK, both of the pages are considered to be entry points.
If we're not on legacy mode, everything works well, since both on SSR and client-side navigation, the client always load the relevant <link> tags of the CSS files needed.
Assuming we're on legacy mode now.
On the first page the user load, there's no need to load JS-inlined CSS, since by SSR there are <link> tags referencing to the relevant CSS files. This was the motivation of PR #9761, that canceled CSS-inlining by JS for entry points, since they are already loaded by SSR.
But on our case, the SSR loads initially only the CSS files for the first page, but not to the second one.
When the user use the client side navigation to the second page, neither of the CSS files or the JS-inlined CSS is loaded! The former doesn't get loaded because we're on legacy mode, and the second isn't loaded because of PR #9761.
Solutions
As the last paragraph suggests, we have three possible solutions:
- Loading the CSS files like in modern mode. This is the most elegant solution in my opinion, and was done in PR feat: support preloading also on legacy bundle #9920.
- Revert PR perf: legacy avoid insert the entry module css #9761, which then will inline the CSS always on legacy, no matter if it's entry point or not. The problem of course is the original issue it solved, that the JS output will be larger since it contains the inlined-CSS, which is might be duplicated since the CSS files might be already loaded on SSR. Therefore, I suggest also the following next solution.
- Perform the CSS-inlining in a different JS file for each entry points. This way, on Vite preloading(which is essentially the Vite client-side navigation ability) in legacy mode, Vite will check if the CSS assets where already loaded, and only if not, Vite will import the JS file representing the relevant CSS-inlining. This way there the client will never (at the same session) need to load the same asset twice, once as CSS and once as JS.
Reproduction
See the code and the online preview in the readme desctiption(you need to use legacy browser for see the issue of CSS missing on navigation): https://github.com/Tal500/sveltekit-legacy-demo#online-preview
System Info
Not relevant.Used Package Manager
npm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.