Closed oalexdoda closed 3 weeks ago
Some ideas:
Any way to get something like this in MUI natively?
It would be awesome to move to a static extraction styled()
API. I'm adding it as a feature candidate for Material UI v6: #30660.
The biggest challenges would likely be:
The solution could be to make this runtime-less a "mode". Meaning something that developers can progressively migrate to. Typically when they want to benefit from RSC (#35993).
Other ideas:
The end goal is to get points c. and d. as close as possible to a.
https://mui.com/system/getting-started/usage/#performance-tradeoffs.
To be fair, d. seems good enough in most cases. It's usually not good enough when you have a large DOM, at which point, you need to rewrite a bit how the styles are applied, which costs you time.
If you open https://pagespeed.web.dev/report?url=https%3A%2F%2Fmui.com%2F&form_factor=mobile, it's not "insanely great" as would say Steve Jobs, this would likely help.
Plus, Server-side React Component could help a lot, for which, we need MUI System to be compatible with #35993. Success would like having 100/100 in:
https://pagespeed.web.dev/analysis/https-mui-com/z9cmpqb6ka?form_factor=desktop
@altechzilla I would recommend that instead of using sx with the components create a separate file and use makestyles for HTML semantics and styled for MUI components. In this way you can reuse a styled component in anywhere in your project instead of redefining it and it also helps in a way that with every reload of the page your inline styling will not be rendered and you can always apply lazy loading on the components which are less important.
I think that exploring https://github.com/cristianbote/goober could also be great, it could already yield a great improvement see the benchmark https://twind.dev/handbook/introduction.html#benchmarks.
Agree, I remember we discussed this in the past, maybe even trying with a custom styled-engine adapter to be optionally added (and if it proves to be success we can promote this adapter as a default). I could try to create a dirty poc soon about this.
We could also rewrite the MUI System implementation, it's slower than it needs to be.
👍 we could actually start investigating this in Q1 2023
Another idea would be to use a utility classes for the sx
prop, meaning we can keep the same object syntax, but transform each key value pair to a utility class. We are likely going to need to drop some of the functionality it has but it could be a start. Developers can then also use the className
prop instead of sx
. I remember we started investigating this two years ago, but from what I remember back then we didn't pursue with it because developers would need to load additional css in their project statically.
Goober was explored a bit in https://github.com/mui/material-ui/pull/27776
Goober was explored a bit in https://github.com/mui/material-ui/pull/27776
Thanks for linking it, I will check to see what was missing
Kinda wish Emotion was optional to some degree to avoid complexity and issues like: https://github.com/mui/material-ui/issues/34910 https://github.com/vercel/turbo/discussions/2312#discussioncomment-3966587
It would be great if MUI styles would rely entirely on css class composition (as mentioned in https://github.com/mui/material-ui/issues/34826#issuecomment-1291693785), similar like DaisyUI build with Tailwind. That could power different themes like Material UI
, Joy UI
customised with different CSSVars
I agree with @altechzilla and @dohomi
In fact, it would be ideal if MUI is tightly integrated with Tailwind and can be configured as Tailwind CSS plugin.
On the MUI side, Tailwind CSS class composition can be used to develop internally.
On the End-User side, not only it is simpler to add Tailwind plugin in Next.js (unlike integrating with Emotion), but we can also get IntelliSense in Visual Studio Code when using the Tailwind CSS IntelliSense extension:
This allows MUI to expose CSS class names which can be used to decorate plain HTML elements as alternative to writing with React component. For example:
<Alert severity="error">This is an error alert — check it out!</Alert>
can be
<div className="alert alert-error">This is an error alert — check it out!</div>
hi self-recommendation, I implemented one, if needed I can transfer this library to mui
styils🤠
I believe @stitches/react would also be a good option. Haven't worked with it, but if I read the introduction correctly it does almost everything emotion does but with better SSR support.
@gijsbotje I think that Material UI needs static CSS extraction, so not stitches, e.g. https://github.com/nextui-org/nextui/discussions/1035
@gijsbotje I think that Material UI needs static CSS extraction, so not stitches, e.g. https://github.com/nextui-org/nextui/discussions/1035
Yeah upon further reading it looked like it wasn't maintaned very well.
Seems like Chakra UI (another UI library dependent on Emotion) is going to switch away from Emotion and to a zero runtime CSS-in-JS solution called Panda:
Zero runtime CSS-in-JS [Panda]
This is the most common and most challenging request we get from users.
Runtime CSS-in-JS and style props are powerful features that allow developers to build dynamic UI components that are composable, predictable, and easy to use. However, it comes at the cost of performance and runtime.
With the release of React Server Components, providing the ability to write Chakra UI components on the server has become crucial. This is a huge win for performance, development, and user experience.
We're building a new, framework-agnostic styling solution that keeps most of the great features of Chakra's styling system but extracts styles at build time. It'll also feature a PostCSS plugin that extracts styles at postcss run time during development.
Panda will leverage new modern platform features like CSS variables, cascade layers, and W3C token spec.
https://www.adebayosegun.com/blog/the-future-of-chakra-ui
🤔 Wonder if it would make sense to combine efforts between MUI and Chakra UI...
https://github.com/chakra-ui/panda https://panda-css.com/
Panda has been released couple days ago and look a lot like what we need for MUI.
Moving to panda-css appears to be a good strategy, but considering the existence of projects utilizing the styled
and sx
syntax, what impact will it have on the developer experience (DX)?
It would be beneficial to have a script in place that converts the current approach or an internal backwards compatibility mechanism, enabling the translation of the existing styled
and sx
syntax into panda-css
syntax. Alternatively, introducing a distinct styling utility called css
while deprecating the other methods could be another solution.
It is important for developers to be aware that this package is currently in alpha, and there may be potential breaking changes.
I think if anything happens to sx
there should absolutely be a codemod that updates everything automatically and a very thorough migration guide. We have thousands of components that would require updating and it would be impossible to update everything manually.
A codemod which would have to work for scenarios where sx
is composed dynamically (i.e. with conditionals, spread objects, etc.), and all the different ways MUI uses it.
Panda is working on supporting styled
syntax:
https://github.com/chakra-ui/panda/discussions/808#discussioncomment-6263046
Panda is working on supporting
styled
syntax:
https://github.com/chakra-ui/panda/pull/786 has been merged.
I think if anything happens to
sx
there should absolutely be a codemod that updates everything automatically and a very thorough migration guide. We have thousands of components that would require updating and it would be impossible to update everything manually.A codemod which would have to work for scenarios where
sx
is composed dynamically (i.e. with conditionals, spread objects, etc.), and all the different ways MUI uses it.
Ideally the sx
prop will work the same but use panda css under the hood.
Seen this? https://stylex-docusaurus.vercel.app/docs/
@altechzilla and @arobert93
Panda supports the same API as emotion (except that the sx
prop has been renamed to css
, but is otherwise equivalent)
You can still use the styled(...)
factory function as you could with emotion:
StyleX has been delayed for a long time but it seems like they're close to releasing it now, so that would probably get my vote. It seems to tick all the boxes:
My only gripe is that the DX seems to be a little awkward in places, like named imports for variables and some verbose syntax. But this gripe would be very minor for me personally.
Overall, it seems to be a great fit for MUI. Here's an apt quote from the docs.
For years, we have had to choose between "Design System" components that come with styles baked in but can be difficult to customize or "Headless" components that are completely unstyled. StyleX finally lets you build UI components that can have default styles and still be customizable.
https://stylex-docusaurus.vercel.app/docs/learn/thinking-in-stylex/
It seems MUI explores a possibility of using stylex in this Reddit thread
@o-alexandrov I explored a bit stylex but after reviewing the design documents produced by Brijesh who's been leading the effort, I have mixed feelings about arguing for it. The main issue I see is that it would be much harder to preserve compatibility of MUI by using stylex. I will agree that having a styling engine that is not MUI specific would be great. The fact that it's backed by meta is a strong argument as it can lead to a big adoption through the react ecosystem. But yeah I don't think I'll argue for it at this point.
We have an internal notion doc that summarizes the pros/cons of other style engines, if someone with access to it can publish it it could help understand the decision.
Is there any progress on this or at least a consensus? Many developers including myself are very excited about RSC but cannot proceed with them due to MUI components being forcefully SSR'ed. I would really appreciate it if I could track progress and get involved in discussions or development.
@brijeshb42 it would be good if you could reply to @abriginets. I could generalise about why our zero runtime solution is a better fit, but it would be better coming from the race-horses mouth. 🙂
I think if anything happens to
sx
there should absolutely be a codemod that updates everything automatically and a very thorough migration guide. We have thousands of components that would require updating and it would be impossible to update everything manually.
As the author of a good chunk of the codemods for the last major (with significant contribution and refinement from others of course) I can assure you that we won't deviate from that path. It always surprises me when people ignore the tools provided, and then complain about how hard the migration was, but if we don't provide them, then the critique will be valid.
That said, we should also try to minimise the amount of breaking changes, and perhaps more frequent majors area way to achieve that by spreading the load.
TLDR - it's not possible with the current API surface of stylex.
As @romgrk pointed out, until styled provides customization at build time level for library authors, it won't be possible to integrate it with our libraries. And even if we are somehow able to do it, it will be a completely different API, thus breaking stuff for our users, especially styled
function and sx
prop.
Having said that, we are anyways working on our own zero runtime library where we are right now testing out perf gains and ironing out the end-user API. If in future, if stylex allows the types of customization that we want, we can experiment with abstracting it's usage inside our zero runtime library itself while still providing users with somewhat similar APIs that are there right now.
Btw, today, Meta finally open sourced stylex:
Material UI v6 is now stable and supports static CSS extraction via Pigment CSS. Thanks for participating in the discussion. We hope you can try Pigment CSS out and provide feedback. I am closing this issue.
This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.
[!NOTE] We value your feedback @oalexdoda! How was your experience with our support team? If you could spare a moment, we'd love to hear your thoughts in this brief Support Satisfaction survey. Your insights help us improve!
(issue heavily edited by @oliviertassinari)
Summary 💡
I recently found an article that breaks down in detail why CSS-in-JS doesn't have the best performance https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b. One of the core features I'm using with MUI is the
sx
/ Emotion / CSS-in-JS feature.This is a proposal to provide a new style engine inspired by the zero-runtime CSS-in-JS libraries: extract all the CSS-in-JS, split it into CSS modules when building the app for production, and serve the styles that way instead. The goal is to retain as much as possible of the current API while having no runtime.
There should be as few breaking changes as possible, and provide a progressive migration story. We wouldn't deprecate the other style engines.
Examples 🌈
Motivation 🔦
The current CSS-in-JS runtimes:
We have seen developers use Tailwind CSS because they are afraid that Material UI is not fast enough. But by moving, they get, what we could argue is a poorer DX with the utility CSS class name. The problems a. you unlearn CSS with utility classes, b. the utility classes are harder to use for conditional styling.
Also, this example shows that it's all about the perception of performance and not the actual performance. Having no runtime would make it very clear that the performance should "logically" be equivalent.
What success looks like?
Two ways to quantify success in this effort:
Bundlesize. Material UI with emotion + its client-side components + its theme adds ~25k gzipped of JavaScript vs. Tailwind CSS.
Benchmarks