`makeStyles` API creates thousands of `<style>` tags synchronously
See original GitHub issueWe use hooks with dynamic props extensively. I might even say it completely got out of hand, our codebase basically has hooks for every CSS property you can set, for example:
const { widthClass } = useWidth({ width })
const { fullWidthClass } = useFullWidth({ fullWidth })
const { maxWidthClass } = useMaxWidth({ maxWidth })
const { flexChildClass } = useFlexChild({ flexGrow, flexShrink, alignSelf })
const { spacingClass } = useSpacing(props)
const { verticalSpacingClass } = useVerticalSpacing({ verticalSpacing })
const { horizontalSpacingClass } = useHorizontalSpacing({ horizontalSpacing })
const { overflowClass } = useOverflow({ overflow })
However, this extensive usage is super bad for performance, as it seems the hooks API creates and injects 1) empty styles 2) synchronously.
The profile starts here: https://github.com/mui-org/material-ui/blob/d4c7c0586bb7853705ed1337f3f8392eb892a1bc/packages/material-ui-styles/src/makeStyles/makeStyles.js#L225 and ends up here: https://github.com/cssinjs/jss/blob/0b17c5d9717141565e466ea0dafdf3ccbe86df5a/packages/jss/src/DomRenderer.js#L335
However, up to 99% of the <style>
tags end up empty:
> [...document.querySelectorAll('[data-jss][data-meta="makeStyles"]')].length
1227
> [...document.querySelectorAll('[data-jss][data-meta="makeStyles"]')].filter(e => e.innerHTML.trim() === '').length
1215
> 1215 / 1227
0.9902200488997555
- This is not a v0.x issue.
- I have searched the issues of this repository and believe that this is not a duplicate.
Possibly related to https://github.com/mui-org/material-ui/issues/16111 maybe?
Expected Behavior 🤔
- jss should not create empty style tags
- jss should group DOM updates
Current Behavior 😯
- 99% of the
<style>
tags created by jss are empty - the style tags are inserted inside
useSynchronousEffect
and do DOM thrashing
Steps to Reproduce 🕹
Link: https://www.eversports.style/design/icons
Just loading the page takes ages, navigating between Typography
and Icons
sections takes in the order of 2-3 seconds, on a beefy desktop browser.
sorry for not providing a reduced testcase, but meh, its quite clear whats going on.
Context 🔦
Your Environment 🌎
Tech | Version |
---|---|
Material-UI | v4.2.1 |
React | v16.8.6 |
jss | v10.0.0-alpha.17 |
Issue Analytics
- State:
- Created 4 years ago
- Reactions:22
- Comments:10 (4 by maintainers)
Top GitHub Comments
@wereHamster oh nice, I didn’t know…
Then it becomes:
So most of these are single rule stylesheets.
Most of the rules however are unique. That kind of surprises me… But actually looking at some of the rules makes me facepalm even more…
So there is no deduplication going on …
Lets investigate further…
So we are down to
< 100
unique classname rules, even less when we remove duplicates due to specificity…Well not only do we have all these mostly duplicate rules injected into the head, they also have uselessly unique classnames, which defeats the whole purpose style sharing via classes, and blows up the generated html as well…
@Swatinem I don’t think these style tags are actually empty. When you create a
<style>
element and add the rules to it via JS API (which many of the CSS-in-JS solutions do, due to performance reasons), then the resulting CSS won’t show up as theinnerHTML
string. You should usedocument.styleSheets
to enumerate all stylesheets and then check.rules.length
to see if they are really empty.