-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
fix(css): avoid duplicate style for server rendered stylesheet link and client inline style during dev #20767
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
Conversation
commit: |
…er_rendered_stylesheet_link
…er_rendered_stylesheet_link
…er_rendered_stylesheet_link
…er_rendered_stylesheet_link
…er_rendered_stylesheet_link
|
This means there'll be two requests for each CSS imports (one for |
|
Right, obviously it's not perfect either, but I think it's worth the try. I don't think this change itself has downside. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The life cycle feels strange to me, but I think that shouldn't be a blocker for this PR.
If <link> works better than <style>, we can migrate to it, rewriting import './foo.css' to client.injectStyle('./foo.css') which will inject a link tag.
Will think about it. There's something tricky with css module though (and likely other build-time css-in-js like solution which generates css). Js needs to know class name mapping, so
|
…er_rendered_stylesheet_link
| datasource | package | from | to | | ---------- | ------- | ----- | ------ | | npm | vite | 7.1.9 | 7.1.10 | ## [v7.1.10](https://github.com/vitejs/vite/blob/HEAD/packages/vite/CHANGELOG.md#small-7110-2025-10-14-small) ##### Bug Fixes - **css:** avoid duplicate style for server rendered stylesheet link and client inline style during dev ([#20767](vitejs/vite#20767)) ([3a92bc7](vitejs/vite@3a92bc7)) - **css:** respect emitAssets when cssCodeSplit=false ([#20883](vitejs/vite#20883)) ([d3e7eee](vitejs/vite@d3e7eee)) - **deps:** update all non-major dependencies ([879de86](vitejs/vite@879de86)) - **deps:** update all non-major dependencies ([#20894](vitejs/vite#20894)) ([3213f90](vitejs/vite@3213f90)) - **dev:** allow aliases starting with `//` ([#20760](vitejs/vite#20760)) ([b95fa2a](vitejs/vite@b95fa2a)) - **dev:** remove timestamp query consistently ([#20887](vitejs/vite#20887)) ([6537d15](vitejs/vite@6537d15)) - **esbuild:** inject esbuild helpers correctly for esbuild 0.25.9+ ([#20906](vitejs/vite#20906)) ([446eb38](vitejs/vite@446eb38)) - normalize path before calling `fileToBuiltUrl` ([#20898](vitejs/vite#20898)) ([73b6d24](vitejs/vite@73b6d24)) - preserve original sourcemap file field when combining sourcemaps ([#20926](vitejs/vite#20926)) ([c714776](vitejs/vite@c714776)) ##### Documentation - correct `WebSocket` spelling ([#20890](vitejs/vite#20890)) ([29e98dc](vitejs/vite@29e98dc)) ##### Miscellaneous Chores - **deps:** update rolldown-related dependencies ([#20923](vitejs/vite#20923)) ([a5e3b06](vitejs/vite@a5e3b06))
Description
Currently Vite reuses server rendered
<style data-vite-dev-id="...">when the same css is imported on client. This PR adds the same logic for<link data-vite-dev-id="...">.I haven't thought through the whole scenario, but this seems reasonable to have since Vite handles link stylesheet with special behavior such as:
<link rel="stylesheet" />supports HMR by rewritinghref="...?t=..."vite/packages/vite/src/client/client.ts
Lines 200 to 201 in bc6995e
vite/packages/vite/src/node/plugins/importAnalysisBuild.ts
Line 118 in bc6995e
additional context
As far as I know, only Astro makes use of
<style data-vite-dev-id="...">for SSR to avoids duplicate css when the module on client imports the same css. Frameworks not using this trick but still injecting css from SSR to avoid FOUC have duplicate CSS on browser momentarily and then remove the server rendered<style>on hydration (Sveltekit, Nuxt, React router work like this). This behavior seems mostly harmless, but there's one issue about potential font glitch (cf. unjs/fontaine#665).I'm trying to see if the same idea can be implemented for
<link data-vite-dev-id="...">. The advantage oflinkoverstyleis following:<style>during SSR, it requiresssrLoadModule("...css?inline")to get the css content whereas<link>requires only module url.<style>can SSR output.<link>by default (unless framework has some logic to inline them).Btw, I'm currently using custom plugin to transform
@vite/clientto have this patch in hi-ogawa/vite-plugins#1168.One more thought: it would be simpler if
updateStyle/removeStylehandleshrefurl directly instead of extradata-vite-dev-id. I haven't tried this yet though.