vanilla-extract icon indicating copy to clipboard operation
vanilla-extract copied to clipboard

Shared CSS is bundled multiple times with App Router in Next

Open samkingco opened this issue 1 year ago • 9 comments

Describe the bug

If you have a component that's shared between a layout.tsx and a page.tsx, then the bundled CSS is output multiple times. This behaviour is different to the pages directory, and results in larger bundle sizes due to duplicate CSS.

Here's a quick screenshot of the Button element in the repo that is share by the layout and the page. You can see the two separate CSS files with the same declarations. This is true of both dev and production builds.

CleanShot 2023-05-10 at 15 38 03@2x

Reproduction

https://github.com/samkingco/vanilla-extract-app-dir

System Info

System:
    OS: macOS 13.2.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 1.31 GB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm
    Watchman: 2022.10.24.00 - /opt/homebrew/bin/watchman
  Browsers:
    Brave Browser: 107.1.45.123
    Chrome: 113.0.5672.92
    Firefox: 109.0
    Safari: 16.3
  npmPackages:
    @vanilla-extract/css: ^1.11.0 => 1.11.0
    @vanilla-extract/next-plugin: ^2.1.2 => 2.1.2
    @vanilla-extract/recipes: ^0.4.0 => 0.4.0
    webpack: 5.74.0 => 5.74.0

Used Package Manager

npm

Logs

No response

Validations

samkingco avatar May 10 '23 14:05 samkingco

This is true for Solid Start as well

cs-clarence avatar May 14 '23 04:05 cs-clarence

Need to speak to the Next team about how to handle this. Will report back.

mattcompiles avatar May 15 '23 01:05 mattcompiles

We've perhaps noticed a similar issue. Using the app router, the transpiled contents from *.css.ts files are also included in the client bundle even if the *.css.ts file is only imported for server components. As a result, the first js load of a page is increased. The tree shaking of the Vanilla-extract related code seemed to work much better with the page router.

I've created a quick codesandbox: https://codesandbox.io/p/sandbox/quizzical-kate-rfmpri?file=%2F.codesandbox%2Ftasks.json%3A22%2C40

In this sandbox, the next project will be build and print out the file contents in .next/static/chunks/app/page-*.js. It will include the js for page.css.ts even though it is only used for a server component:

{container:function(){return e},container2:function(){return f}}),t(3786);var e="_1ogfafu0",f="_1ogfafu1"}

dpnolte avatar May 24 '23 17:05 dpnolte

Hey! This isn't specifically related to vanilla-extract, it's the current behavior if you use global CSS or CSS modules in app/ as well. And we're thinking about improving it.

The tricky part is that a layout and a page will not always render together. It's possible that another page that doesn't contain these styles is under the same layout. In pages/ one route is just one entry so all styles are combined together, but now there're multiple entries that won't always be rendered together.

However, I'll let you know if we make any progress there!

shuding avatar May 26 '23 07:05 shuding

https://github.com/vercel/next.js/pull/50406 should fix this!

shuding avatar May 29 '23 11:05 shuding

@shuding it seems to still happen on [email protected]

CleanShot 2023-10-13 at 10 33 00@2x

okonet avatar Oct 13 '23 08:10 okonet

@shuding it seems to still happen on [email protected]

I want to solve this problem bb.. 스크린샷 2023-11-09 오전 1 39 54

thdwlsgus0 avatar Nov 08 '23 16:11 thdwlsgus0

I just faced this problem on [email protected].

otaviosoares avatar Nov 11 '23 05:11 otaviosoares

This seems similar to #1276. Apparently next 14.1.3 fixes duplicate styles in prod (they're still present in dev). Your reproduction no longer exists, so I can't test it.

askoufis avatar Mar 29 '24 07:03 askoufis