experimental.inlineCss: stylesheet duplicated twice in the flight payload — _full.segment.rsc carries the CSS text 2x (3x total per prerendered page)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/TulmansMeubelen/next-inlinecss-flight-duplication-repro
To Reproduce
npm installnpm run build(next build --turbopack)node count.mjs— counts occurrences of the CSS marker (@layer properties) in the build artifacts
The repro is intentionally tiny: a root layout importing one global stylesheet, one app/[locale]/page.tsx with generateStaticParams, and experimental: { inlineCss: true }.
Current vs. Expected behavior
Current (both 16.3.1 and 16.4.0-canary.12):
| artifact | copies of the CSS text |
|---|---|
.next/server/app/nl.html |
3 (1 <style> + 2 flight rows) |
.next/server/app/nl.rsc |
2 |
.next/server/app/nl.segments/_full.segment.rsc |
2 |
.next/server/app/nl.segments/_index.segment.rsc |
1 |
| every other segment file | 0 |
The two flight copies are byte-identical T-rows, each referenced by its own hoistable style element row (["$","style","1",{"precedence":"next","href":"<chunk>.css","children":"$<id>"}]). Both land in the first flushes of the stream. Since the individual segments together only carry one copy, the second copy appears when the full flight (_full.segment.rsc) is assembled — the assembly re-serializes the hoistable stylesheet instead of reusing the already-emitted row.
Expected: at most one copy of the CSS text in the flight payload — the inlineCss docs describe exactly one RSC-payload copy as the known trade-off ("Styles are duplicated during initial page load - once within <style> tags for SSR and once in the RSC payload"), i.e. 2 copies per document, not 3.
Provide environment information
Operating System:
Platform: win32
Arch: x64
Version: Windows 11 Pro
Available memory (MB): 32679
Available CPU cores: 16
Binaries:
Node: 24.11.1
npm: 11.6.2
Relevant Packages:
next: 16.4.0-canary.12 (also reproduced on 16.3.1)
react: 19.2.8
react-dom: 19.2.8
typescript: 7.0.2
Which area(s) are affected? (Select all that apply)
CSS, Turbopack, Runtime
Additional context
On a real Tailwind application the inlined stylesheet is large (ours is 249 KB), so the extra flight copy is expensive: every prerendered/ISR-written HTML document carries ~500 KB of flight CSS on top of the 255 KB <style> block. On Vercel this roughly triples ISR write units and fast origin transfer for HTML documents (we measured a content page at 1,174 KB with the flag vs 415 KB without; the third copy alone is ~250 KB per page). Deduplicating the flight copy would remove ~21% of every prerendered page at no functional cost.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run npm install, npm run build, and node count.mjs in the linked reproduction. Compare .next/server/app/nl.rsc and _full.segment.rsc with the individual segment files, then trace how the full flight is assembled. Done means the CSS marker occurs at most once in the RSC payload while the reproduction still builds successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, next.js, react, typescript
- Domain
- build-system, performance, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100