-
-
Notifications
You must be signed in to change notification settings - 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! |
closes #42772, closes #47099
For Reviewer
Theme
tostylesOptimized
to remove cyclic deps and set theme.components to emptyTheme
fromstyles
with augmented theme.components to preserve the behaviorstylesOptimized
tostyles
so that user can switch the import path without breaking change<component>.d.ts
to use from stylesOptimized and export its Theme types for selective augmentationSummary
@mui/material/styles
import with@mui/material/stylesOptimized
including module augmentationTo test the change, checkout this PR:
Then edit the
packages/mui-material/perf-test/test-createTheme.tsx
to import createTheme from@mui/material/styles
and 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'>>
Theme
interfaceTheme
extendsBaseTheme
andCssVarsProperties
, inlining all their type definitionsTheme
is 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'>>
:ComponentsOverrides
andComponentsVariants
uses theTheme
generic with complexInterpolation
types@mui/material
Memory spike: From ~460MB to ~2.2GB (4× increase), causing OOM errors in CI/CD
User Journey:
Solution
Created alternative entry point
stylesOptimized
that breaks circular dependency by moving completeTheme
definition there, makingcreateThemeNoVars.d.ts
reference 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.ts
definesTheme
with simplecomponents?: ThemeComponents
(no generics, no circular references)styles/createThemeNoVars.d.ts
extendsThemeOptimized
instead of defining inlineThemeOptimized
once (fromstylesOptimized
), avoiding repeated instantiationsNon-breaking for v7:
import { ThemeOptions } from '@mui/material/styles'
as beforeTheme
interface still usesComponents<T>
generic for backward compatibility@mui/material/stylesOptimized
for better build performancePerformance impact (from analysis):
Usage for Library Authors
To benefit from improved TypeScript performance, replace ALL imports from
@mui/material/styles
with@mui/material/stylesOptimized
:Important:
@mui/material/styles
will work but with higher memory usagestylesOptimized
for CI/CD stabilityResult
Before:
After: