Skip to content

fix(client): skip rewriting unchanged adopted styles - #23697

Merged
sapphi-red merged 2 commits into
vitejs:mainfrom
xyrolle:fix/client-skip-unchanged-style
Oct 8, 2026
Merged

sapphi-red merged 2 commits into
vitejs:mainfrom
xyrolle:fix/client-skip-unchanged-style

Conversation

@xyrolle

@xyrolle xyrolle commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

fixes #23696

When the dev client reuses a server-rendered <style data-vite-dev-id>, updateStyle writes the module's CSS into it even if it's the same text. In Chrome 154 that replaces the stylesheet and re-creates its @font-face rules, the fonts get revalidated, and a font-display: optional font that's still loading at render time falls back for good.

This only writes when the text is different. HMR updates that change the CSS work as before. One thing that changes: if something edited the stylesheet through the CSSOM, an update with the same text no longer resets it.

For the test I added a css-style page to the hmr playground, next to css-link. A small plugin renders the <style data-vite-dev-id> the way an SSR framework would, and a script counts mutations of that style. The test checks that loading the module leaves the style alone (one style, zero mutations) and that editing the file still updates it. Without the fix it gets [1, 1]. Because it counts mutations, it also catches the rewrite in Playwright's Chromium, where the font symptom itself doesn't show.

I used an AI assistant while investigating and drafting this. I reviewed the change myself: I read updateStyle and ran the new test without the fix (fails with [1, 1]) and with it (passes).

`updateStyle` reuses a server-rendered `<style data-vite-dev-id>` and then
sets its `textContent` to the module's CSS, even when the text is already
the same. Chrome 154 replaces the stylesheet on that write and re-creates
the font faces it declares. Those fonts are then revalidated, since the dev
server serves them with `Cache-Control: no-cache`, and a
`font-display: optional` font that is still loading when the page renders
stays on its fallback.

Only write the CSS when it differs.
@ghost ghost added bot: maybe Maybe a bot, LLM, or agent feat: css p2-edge-case Bug, but has workaround or limited in scope (priority) labels Oct 8, 2026

ghost commented Oct 8, 2026

Copy link
Copy Markdown
Member

It seems this is related to https://chromium-review.googlesource.com/c/chromium/src/+/8252693. But regardless of that, I think it's good to have this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot: maybe Maybe a bot, LLM, or agent feat: css p2-edge-case Bug, but has workaround or limited in scope (priority)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dev client rewrites a server-rendered <style data-vite-dev-id> with identical CSS, and Chrome 154 then drops font-display: optional fonts

2 participants