Skip to content
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

Bundling MUI w/ Pigment CSS results in large JavaScript chunks #44113

Open
o-alexandrov opened this issue Oct 15, 2024 · 4 comments
Open

Bundling MUI w/ Pigment CSS results in large JavaScript chunks #44113

o-alexandrov opened this issue Oct 15, 2024 · 4 comments
Assignees
Labels
package: pigment-css Specific to @pigment-css/* status: waiting for maintainer These issues haven't been looked at yet by a maintainer

Comments

@o-alexandrov
Copy link

o-alexandrov commented Oct 15, 2024

Steps to reproduce

Link to live example

Steps:

  1. Clone the repo (it's exactly the same as the vite example from this repo)
    • I just added rollup-plugin-visualizer so you could visualize the resulting bundle
  2. Bundle npm run build
  3. Your browser will open automatically with the result from rollup-plugin-visualizer (see example below)
Screenshot 2024-10-15 at 1 41 25 PM

Current behavior

  • emotion is still in the final bundle, but takes less space (as expected) 2.32KB gzipped
  • zero-runtime-theme.js is 7.16KB gzipped
  • @pigment-css/react/build is 6.74KB gzipped

Total: 16.22KB gzipped

Expected behavior

Smaller JavaScript footprint

Context

We should evaluate the runtime implications of some PigmentCSS' API usage, such as: styled that results in extra JS output

Your environment

npx @mui/envinfo
  System:
    OS: macOS 15.0.1
  Binaries:
    Node: 22.9.0 - /opt/homebrew/bin/node
    npm: 10.8.3 - /opt/homebrew/bin/npm
    pnpm: 9.9.0 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 129.0.6668.91
    Edge: 112.0.1722.39
    Safari: 18.0.1
  npmPackages:
    @emotion/react:  11.13.3 
    @emotion/styled:  11.13.0 
    @mui/core-downloads-tracker:  6.1.3 
    @mui/material: latest => 6.1.3 
    @mui/material-pigment-css: latest => 6.1.3 
    @mui/private-theming:  6.1.3 
    @mui/styled-engine:  6.1.3 
    @mui/system:  6.1.3 
    @mui/types:  7.2.18 
    @mui/utils:  6.1.3 
    @pigment-css/react:  0.0.24 
    @pigment-css/vite-plugin: latest => 0.0.24 
    @types/react: latest => 18.3.11 
    react: latest => 18.3.1 
    react-dom: latest => 18.3.1 
    typescript: latest => 5.6.3 

Search keywords: pigmentcss, pigment, bundling, final, emotion, zero runtime

@o-alexandrov o-alexandrov added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 15, 2024
@mnajdova
Copy link
Member

mnajdova commented Oct 16, 2024

In general, we are talking about two different things here, runtime performance vs bundle size. In general, we made a decision to make the theme available in the runtime too for some use-cases, like having access to it in the rendering logic etc. So, I would say that part of the bundle size increase is expected. In terms of how much code is being executed during runtime, from my understanding all of it is related to:

  • applying the right CSS var based on props
  • applying the right classname based on props

So zero-runtime namely means that there is no logic in generating stylesheet during runtime - this is the thing that is different than Emotion. @brijeshb42 can correct me or expand further.

Now, we may need to document these things so we don't set false expectations.

A question - have you compared a plain app using Emotion vs Pigment CSS? Is this related to adding Material UI too in the bundle? We can likely move this issue to the Pigment CSS repository

@brijeshb42
Copy link
Contributor

Current bundle size for zero-runtime-theme is controlled through @mui/material package. Pigment itself is only responsible for @pigment-css/react/build and that too would depend on the APIs that you are using and whether the bundler is tree-shaking unused exports or not.
As for emotion being part of the bundle, I'll need to inspect the source and get back but ideally it should not be part of the bundle.
As Marija already pointed out, zero-runtime here purely means that the css generation is not dependent on the runtime (whether browser or server). The actual bundle size will depend on how it is implemented. In this case, @mui/material is also injecting it's theme at runtime (through hooks in Pigment CSS) so that it is backward compatible.

@o-alexandrov
Copy link
Author

Idk whether this issue can be improved by rethinking how you use the PigmentCSS’ API (styled vs css), or by optimizing runtime implications of the styled API.

  • depending on this, you might want to either move this to PigmentCSS repo, keep it here, or close this issue as not planned

On a side note, for my use case, the JS only size of an app actually grew in size after switching from Emotion to PigmentCSS.
That's because @emotion-related deps still ended up in the final bundle (probably because @mui/lab or @mui/base are not processed with transformLibraries: ["@mui/material"])

For me, what worked to remove emotion completely was setting transformLibraries: ["@mui"]

  • but, this probably won't work for everyone, as probably not all mui-x components are adjusted for PigmentCSS

@zannager zannager added the package: pigment-css Specific to @pigment-css/* label Oct 16, 2024
@o-alexandrov
Copy link
Author

o-alexandrov commented Oct 16, 2024

what worked to remove emotion completely was setting transformLibraries: ["@mui"]

I mean to decrease use of emotion in a medium project with a lot of MUI components to 2.32KB gzipped as in the provided reproduction example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: pigment-css Specific to @pigment-css/* status: waiting for maintainer These issues haven't been looked at yet by a maintainer
Projects
None yet
Development

No branches or pull requests

4 participants