[material][styles] Add optimizedTheme type feature to reduce TS instantiations - #49004
Open
siriwatknp wants to merge 2 commits into
Open
[material][styles] Add optimizedTheme type feature to reduce TS instantiations#49004siriwatknp wants to merge 2 commits into
siriwatknp wants to merge 2 commits into
Conversation
1 task
Deploy previewBundle size
Check out the code infra dashboard for more information about this PR. |
siriwatknp
marked this pull request as ready for review
August 21, 2026 09:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #42772, closes #47099
Alternative to #47069 based on this analysis.
Summary
Type checking a custom theme forces TypeScript to instantiate the types of all components through
theme.components. In large projects this slows down type checking and can cause out-of-memory errors in CI.This PR adds an opt-in
optimizedThemetype feature. Users enable it with one module augmentation, no import changes:With the flag on,
theme.componentsbecomes a looseThemeComponentsinterface. Type safety comes back per component through augmentation:Measured with the new
test/ts-performanceworkspace against the built package (TypeScript 6.0.3):styles/root barrel importsWhy not a separate entry point (#47069)
The
stylesOptimizedentry point restores the strict types through a global module augmentation, so one import of@mui/material/stylesor@mui/materialanywhere in the program disables the optimization. Dependencies (MUI X, Toolpad, theme libraries) make this unavoidable for most real apps. Measured: one 2-line file importingcreateTheme({})fromstylestakes the pristine program from 187 back to 145k instantiations.The flag is immune to this: it is not tied to import paths, so stray imports and dependencies cannot turn it off. It also keeps a single
Theme/ThemeOptionsidentity, so existing ecosystem augmentations of@mui/material/styleskeep working, and no mirror entry point or codemod is needed.For Reviewers
TypeFeaturesandThemeComponentsare declared increateThemeNoVars.d.ts, following the same pattern as the existingCssThemeVariablestoggle.Components<...>(Theme/ThemeOptions,CssVarsThemeOptions,ThemeWithProps) now go throughResolvedComponents<T>, a conditional type that picksThemeComponentswhen the flag is on. Conditional type branches are lazy, so the strict branch is never instantiated in optimized mode. With the flag off, resolution is identical to today (verified: same instantiation count).components.tsstill imports every component's props), so parse time remains. The instantiation explosion, which is what causes the OOM, is removed.themeCssVarsAugmentation.test/ts-performanceruns afterrelease:buildin CI (newTest theme type instantiationsstep). A shared fixture customizing every component is checked by two projects: the strict one asserts default strictness with@ts-expect-errorand reports the >100k baseline; the optimized one enables the flag, imports from the root barrel, fails above 20k instantiations, and asserts the selectiveMuiButtonaugmentation still rejects invalid values so a silently dropped augmentation fails CI.To test locally:
pnpm --filter "@mui/material..." build pnpm --filter @mui-internal/test-ts-performance test:performance