-
-
Couldn't load subscription status.
- Fork 32.7k
[material-ui] Reexport styles from stylesOptimized to improve TS performance
#47069
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
base: master
Are you sure you want to change the base?
Conversation
Netlify deploy previewBundle size report
|
b3d075e to
e050e50
Compare
|
@siriwatknp Nice approach! The solution looks good from what I’ve seen. Could we optimize the sx prop with theme too ( |
|
Ran the test and can confirm the numbers. If you need some support with some chores around moving from styles to styles optimized and test stuff lmk :) Edit: This fixes a very "weird" Problem with circular Depdencies regarding const theme1 = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: {
backgroundColor: 'primary.main'
}
}
}
}
});
const theme2 = createTheme(theme1)if you create a theme (theme1) with a const theme1Options: ThemeOptions = {
components: {
MuiButton: {
styleOverrides: {
root: {
backgroundColor: 'primary.main'
}
}
}
}
}
const theme1 = createTheme(theme1Options);
const theme2 = createTheme(theme1Options);
const theme3 = createTheme(theme1 as ThemeOptions)I created an issue for the this behavior, to adress it separatley and would suggest to add a warning to the page. |
I would leave the |
@possum-enjoyer please help test it out (best to test with any existing project to ensure compatibility)! it will help this PR to be merged faster. |
|
From my first Tests I found that some Components were missing a theme like CssBaseline and The x Packages (but I guess they will be updated later on). Everything else was compatible without any problems. No eslint or tsc errors and no refactoring of code was necessary besides changing the import and augmenting the Also for some reason if I split up my custom theme into smaller objects like const MuiButton: ThemeComponents["MuiButton"] ={...};Behaves weird (investigating the type of MuiButton via vscode always pointed me to the old The only thing that was a little bit "painful" was extending the ThemeComponents Type with many Components. It's 5 minutes at most when using a good ide. Besides that, the breaking of this circular dependency reduced tsc buid times drastically (more than 2.5x in one project). Great job finding that problem! Small update: I did a median via hyperfine and before the build time for one project where I changed stuff for around 30 components was ~10 seconds. |
closes #42772, closes #47099
For Reviewer
ThemetostylesOptimizedto remove cyclic deps and set theme.components to emptyThemefromstyleswith augmented theme.components to preserve the behaviorstylesOptimizedtostylesso that user can switch the import path without breaking change<component>.d.tsto use from stylesOptimized and export its Theme types for selective augmentationSummary
@mui/material/stylesimport with@mui/material/stylesOptimizedincluding module augmentationTo test the change, checkout this PR:
Then edit the
packages/mui-material/perf-test/test-createTheme.tsxto import createTheme from@mui/material/stylesand run diagnosis again.Compare the result between the two.
Root Cause
The issue stems from circular TypeScript dependency in the type definitions:
Original definition (
packages/mui-material/src/styles/createThemeNoVars.d.ts):The circular path:
ThemeOptions.components→Components<Omit<Theme, 'components'>>ThemeinterfaceThemeextendsBaseThemeandCssVarsProperties, inlining all their type definitionsThemeis referenced back inThemeOptions→ circular dependencyWhy exponential type computation:
The
Components<Theme>interface is massive - for each of 80+ MUI components, it references:When TypeScript resolves
Components<Omit<Theme, 'components'>>:ComponentsOverridesandComponentsVariantsuses theThemegeneric with complexInterpolationtypes@mui/materialMemory spike: From ~460MB to ~2.2GB (4× increase), causing OOM errors in CI/CD
User Journey:
Solution
Created alternative entry point
stylesOptimizedthat breaks circular dependency by moving completeThemedefinition there, makingcreateThemeNoVars.d.tsreference it instead of defining inline.Key Changes
1. New optimized entry point (
packages/mui-material/src/stylesOptimized/createTheme.d.ts):2. Mirror exports (
packages/mui-material/src/stylesOptimized/index.ts):3. Update original definition (
packages/mui-material/src/styles/createThemeNoVars.d.ts):Why This Works
Breaks circular dependency:
stylesOptimized/createTheme.d.tsdefinesThemewith simplecomponents?: ThemeComponents(no generics, no circular references)styles/createThemeNoVars.d.tsextendsThemeOptimizedinstead of defining inlineThemeOptimizedonce (fromstylesOptimized), avoiding repeated instantiationsNon-breaking for v7:
import { ThemeOptions } from '@mui/material/styles'as beforeThemeinterface still usesComponents<T>generic for backward compatibility@mui/material/stylesOptimizedfor better build performancePerformance impact (from analysis):
Usage for Library Authors
To benefit from improved TypeScript performance, replace ALL imports from
@mui/material/styleswith@mui/material/stylesOptimized:Important:
@mui/material/styleswill work but with higher memory usagestylesOptimizedfor CI/CD stabilityResult
Before:
After: