-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
Suggestion
π Search Terms
performance
emotion
material-ui
getKeyPropertyName
chooseOverload
instantiation
instantiate
large union
β Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
β Suggestion
TL:DR: Determine fast path in getKeyPropertyName() by the count of non-primitives in unions, not just the length of unions.
I'm investigating type check / vscode completion performance issue with material-ui v5, and found this one of root causes.
(See mui/material-ui#19113 (comment) for more detail of the investigation.)
getKeyPropertyName() is (indirectly) called from chooseOverload() to determine argument type matches to the method signature. It has fast path (that returns undefined) for small union with less than 10 constituents.
Currently it checks only one of: "length of union" OR "existence of non-primitive":
if (types.length < 10 || getObjectFlags(unionType) & ObjectFlags.PrimitiveUnion) {This causes eager instantiation of large union type with many primitives + few non-primitives. For example it affects material-ui v5 (mui/material-ui#19113 (comment)) and emotion (emotion-js/emotion#2257).
While I'm not tested with emotion itself, both are using almost the same type. Profiler result of getDiagnostics() when editing the file contains styled() call of material-ui v5 (with some optimization) will looks like this:
This is because they have 10-12 constitutions in the union.
export type InterpolationPrimitive = // length: 10
| null
| undefined
| boolean // true | false
| number
| string
| ComponentSelector
| Keyframes
| SerializedStyles
| CSSObject;
export type Interpolation<Props> = // length: 12
| InterpolationPrimitive
| ArrayInterpolation<Props>
| FunctionInterpolation<Props>;Removing 3 items from InterpolationPrimitive will remove getKeyPropertyName() entry from above profiler result and improves performance (In above environment 170-210ms to <= 20ms).
But it'll break library feature.
So, in getKeyPropertyName(), count non-primitive constitutions instead of length can improve performance for primitives-rich unions.
π Motivating Example
Improves type check performance when you have large union with many primitives.
π» Use Cases
See above.
