A Journey toward better style
- I would like to thank Nathan Marks for the awesome work is has done addressing the styling issues.
- I would like to thank Pete Hunt for his inspiring talk on reusable components.
- I would like to thank the following oranizations for giving me the opportunity to share this topic:
We started looking for the best styling solution available. Nathan Marks built a custom solution for the needs of Material-UI: stylishly. Ultimately we reverted. We think that it's much better to rely on the community. Still, that was a very valuable experimentation.
Regarding the community, looking at the MicheleBertoli's repository. You can tell that there is a lot a solution available.
What's the best one for our needs?
For the sake of this presentation, I have selected 5 libraries that I think have taken valuable tradeoffs. I'm gonna give my point of view in the rest of this section. The information given are biased by my understanding of the reality.
- CSS modules
- Singularity: Extended CSS DSL. Generate style at built time.
- Motivation: Having some isolated and composable module of CSS. Stay as close as possible to the CSS ecosystem.
- Singularity: Per rule style usage and injection.
- Motivation: Khan Academy was looking for a better way to style components with an existing code base. E.g. usage of
- Singularity: Uses post-CSS at runtime.
- Motivation: ? My best guess is, leveraging JS power while still using the CSS syntax.
- Singularity: Has a low-level API.
- Motivation: ? I have no clue. I should be asking @nathanmarks.
- Singularity: Has a functional API.
- Motivation: ? Could be inspired by posts like Functional Programming, CSS, and your sanity.
We can't compare anything without some dimensions. But having too much of them add noise.
- The API.
- Is the API low or high level? The theming requirement is quite high for Material-UI. The much freedom we have, the better.
- Is the API declarative? The more declarative we are, the better.
- Time to first paint.
We have a legacy of poor performance with our inline-style implementation (lake of caching).
Reducing the delay between an interaction and something on the screen is quite critical for us.
I have run a simple benchmark on a modified version of CSS-in-JS
There is quite some factor than can make a difference. I have noticed a factor x2 of difference between the fastest solution (CSS modules) and the slowest one (styled-components).
- Is the style pre-processed at runtime of build time?
- Is the style injected as class names used or upfront during the bootstrap?
- How are the classNames generated? E.g. computing a hash of the rule object could be expensive.
- Library size.
Users of Material-UI could be using a single component out of the available ones.
<DatePicker />. We want to minimize the entry price of using a single component.
- Server Rendering.
Server side rendering a page drastically improve perceived performance for a user first visit (for repetitive one, Service Worker are even more efficient).
Material-UI can't be taken seriously without a strong answer to this point.
- Can requests be parallelized? I.e, not using a singleton, that's also bad for security.
- Is the API allowing streaming the response?
The less coupled with a solution we are the better.
We also want to make sure the solution we are going to use reach a broad audience.
E.g. LESS is used by the Angular and React community. That's increasing odds of success.
- Are we coupled to React?
- Are we coupled to Webpack?
Users of Material-UI were complaining that the debugging experience was poor with inline-style.
Browser dev tool handles much better the CSS.
Still, the styling solution can impact it.
- Are the classNames readable in dev mode?
- Are the classNames injected into a single
styleelement or multiple?
- CSS output size. That last dimension is less interesting. I was just curious.
|Time to first paint||++||o||-||+||o|
|Library size in kB||~0||18||126||22||9|
|CSS output size||o||++||+||+||o|
Material-UI has chosen
JSS. It's addressing our unique needs.
Your needs are most likely different. It could be better for you to use a another solution.
Be sure you make an informed choice
The compared libraries are going to improve. My comparison might not worth anything one year from now.