-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
[system] Pre-serialize & cache styles to improve performance #43412
Conversation
function styleAttachTheme(props) { | ||
attachTheme(props, themeId, defaultTheme) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the various attachTheme
calls in favor of adding a style function that runs once and attaches the theme directly on the props. It relies on running before anything else.
ea7b780
to
bce2ac0
Compare
|
||
// If `tag` is already a styled component, filter out the `sx` style function | ||
// to prevent unnecessary styles generated by the composite components. | ||
processStyles(tag, (styles) => styles.filter(style => style !== styleFunctionSx)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this mutating tag
though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@siriwatknp Maybe you could confirm here, I think this line is mutating tag
's style processors, but what we want is instead to skip adding the sx processor to the new styled component. Is that right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regardless of the question above, I think I'll rename this function to internal_mutateStyles
to better express what it's doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be an (existing) issue/bug but I don't have the bandwidth to investigate it and I'm afraid of fixing it and possibly changing the behavior, so I've just renamed internal_processStyles
to internal_mutateStyles
to better highlight what is happening here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we introduced this as an perf improvement as we were processing sx multiple times if we had a styled component invoked over another styled component. This is what I remember about it. Likely @siriwatknp could have more info, but +1 on not changing any behavior as part of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, @mnajdova is right.
return value; | ||
}; | ||
} | ||
export default memoTheme; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like it shouldn't even be exported #43440
export default memoTheme; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was worried about the typings in the initial PR (memoTheme<T>
), having it here made it easy to include the MaterialTheme
, though material doesn't use much TS from what I can see. I could remove it altogether from material but it would make it less accessible to external users in case they want it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want us to move to a point where we force developers to provide their theme (so we can remove all @mui/system re-exports from @mui/material, so we need a great DX to not rely on a default theme, so this seems OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. So should I remove this file and import unstable_memoTheme
from @mui/system
everywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is beyond the scope of this PR #43440.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, I added the export from @mui/material because I wanted to use it in the lab, for the LoadingButton.
Netlify deploy previewhttps://deploy-preview-43412--material-ui.netlify.app/ PigmentGrid: parsed: +10.25% , gzip: +8.06% Bundle size reportDetails of bundle changes (Toolpad) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, sorry it took a bit longer to get this one in.
I just updated to mui v6 and got problems with one of your changes: I dont know the details about the code, but I was wondering why is
I think this happens when nesting |
Performance optimization, the prop object is being recreated at multiple times in the stack (2x by React, 1x by Emotion, previously about 4-6x by MUI). Do you have a reproducible case you can share? |
Ok, that's understadable. I have a hook |
The prop needs to stay for compat reasons, it's passed to style functions down the line, removing it would be a breaking change. We could pay the performance cost if there is an unsolvable problem, you can file an issue with a reproducible case if you want to discuss it more. |
This PR uses emotion's serializer to pre-serialize stable styles and re-use them on every render, rather than have emotion pass them through
createStringFromObject
every time.TestCase
Results:
Fix #43440
https://deploy-preview-43412--material-ui.netlify.app/performance/table-mui/