[poc] Support a version of Material UI without CSS in JS
This PR serves as a proof of concept of how we can build Material UI components using plain CSS, but still allow CSS-in-JS users to use all of the previously available APIs, like sx prop, styleOverrides etc if they want to. On the other hand, for users that care about performance or want to use plain CSS/Tailwind CSS for customisation, they don't have to pay any penalty of bundle size or performance that comes from using CSS-in-JS.
The PR also includes the changes from https://github.com/mui/material-ui/pull/46001.
Example projects:
- Example using Tailwind CSS - https://github.com/mnajdova/next-mui-css-modules-tailwind
- Example using Emotion for customisation (all previous APIs available) - https://github.com/mnajdova/next-mui-css-modules-emotion
Initial benchmark:
I did few performance benchmarks and the results are promising. I am comparing the updated Slider component that is created using plain CSS with the previous one that uses Emotion. On top of it I am adding the same customization (using Emotion) as current users have. There are the results I am getting:
Test case 1: Rendering 500 sliders without any customization
Emotion - commit time: 2.8s Plain CSS - commit time: 0.9s (3.1 x faster)
Test case 2: Rendering 500 sliders using sx prop with one CSS property
Emotion - commit time: 2.8s Plain CSS - commit time: 1.1s (2.54 x faster)
Test case 3: Rendering 500 sliders using a long sx prop (iOS Slider example)
Emotion - commit time: 3.3s Plain CSS - 1.8 (1.83 x faster)
Conclusion: In the worst case scenario, the component was 1.8 times faster. The most common use-cases will likely lie somewhere between the Test case 2 and Test case 3, which is still a substantial improvement. For every component that don't need customisation, the gain is already huge (3 times faster). Again, this is a bit of an artificial example, that uses only one component as benchmark but we can already see the size of the impact.
Todos:
- [ ] RTL support - while migrating components we could change the theme to define logical CSS properties, or add the RTL styles together by using a selector
- [ ] dark/light mode support - we can prepare the styles similar to the CSS generated by theme.applyDarkMode
- [ ] CSS injection - we need a simplified CSSVarsInjector component that out of the generated theme creates stylesheet with the CSS variables
We can use the
theme.generateStyleSheets()for this, however, as the functions generates JS syntax stylesheet, I used this converter to convert it to string (very fast AI generated implementation). We can provide it as a util out of Material UI. - [ ] Fix animations in the Slider component
- [ ] Figure out how we want to provide the theme when Emotion is not used (still use context or maybe depend on singleton that people can import - the result of
createTheme)
Netlify deploy preview
Bundle size report
Bundle size will be reported once CircleCI build #832201 finishes.
Generated by :no_entry_sign: dangerJS against fee13d7eed22e3340b4c1b933ccf60eee83c3918
It looks similar to https://gist.github.com/oliviertassinari/5e9031104a86eb5c3325819e9a23857f#muistyled-engine-empty