mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
92.04k stars 31.64k forks source link

Can the typings be simplified to improve performance? #19113

Closed amcasey closed 1 year ago

amcasey commented 4 years ago

As suggested by @eps1lon in #18128, I'm creating this issue as a place to discuss the Material-UI typings and whether they can be simplified to reduce the amount of time spent checking them, especially during editing.

There's always a tension between having the most exact types (which provide the best errors and editor completions) and having the fast type checking (the far end of the spectrum being any).
Issues like https://github.com/microsoft/TypeScript/issues/34801 suggest that Material-UI might benefit from relaxing the exactness in order to gain back some perf.

From the repros I've investigated so far, a lot of the slowness seems to come from the large number of CSS property names (see https://github.com/mui-org/material-ui/blob/master/packages/material-ui-styles/src/withStyles/withStyles.d.ts). Not being an active CSS user myself, I have some naive questions:

1) Am I correct in assuming that having a name and type for each well-known CSS property is incredibly valuable and isn't something we could give up? 2) The CSSProperties type appears to exist to support "pseudo selectors and media queries", which - according to my limited reading - seem to be named bags of additional CSS properties. a) Are these bags themselves recursive or is there only a single additional layer? That is, do you go from width to foo.width or to foo.bar.width, etc? If it's just one level, simplifying the types cuts my local repro from 4.6 seconds down to 3.6 seconds (i.e. big win). b) I played around with the types myself and couldn't come up with anything better than BaseCSSProperties[keyof BaseCSSProperties], but - as I'm guessing you're aware - that's not a very useful type. It basically says that any CSS property can have the type of any (other) CSS property - that's only slightly better than any. 3) In StyleRules, if there are no properties, you get either CSSProperties or () => CSSProperties (which I will sloppily call "thunked CSSProperties"), which makes sense - the CSSProperties might be lazy. If there are properties, you get either CreateCSSProperties<Props>, which makes sense - the Props might be required to compute the CSSProperties - or (props: Props) => CreateCSSProperties<Props>, which I didn't understand because it's effectively double-lazy - you have pass in the Props once to get the CreateCSSProperties and then again to get individual properties. Why is it "double thunked"?

Separately, I suspect, but have yet to demonstrate that IsEmptyInterface is too expensive for the benefit it provides. However, it's quite possible that I don't fully understand the benefits, so it would helpful to hear more.

Can we work together to find the right balance between accuracy and perf? (Note: "just make the compiler faster" is obviously a viable strategy, but I'd like to get the typings to a good place before we optimize for them.) Thanks!

Pains

ypresto commented 4 years ago

@eps1lon with const and without createStyles, IntelliSense does not show context-aware candidates anymore :cry:

amcasey commented 4 years ago

@ypresto It should. Do you have an example code snippet?

ypresto commented 4 years ago

@amcasey

Adding as const to the outer object or the property effectively kills it. I don't want to place it on every property.

const useStyles = makeStyles(theme => ({
  root: {
    // no IntelliSense
  }
} as const))

Also without createStyles it has small limitation for string completion.

const useStyles = makeStyles(theme => ({
  root: {
    direction: '|', // no IntelliSense at | (works with createStyles)
    direction: | // IntelliSense works at |
  }
}))
amcasey commented 4 years ago

@ypresto By "kills it", do you mean "causes it to work the same way as createStyles did"?

It's a drag to put it everywhere, but no more of a drag than putting createStyles everywhere.

ypresto commented 4 years ago

@amacleay I meant kills IntelliSense :pray:.

amcasey commented 4 years ago

Sorry, I missed your comments. I'll give that a shot.

ypresto commented 4 years ago

I have no idea why but this is 1100ms → 750ms, interestingly:

 export const DropArea: React.FC<CardProps & {
   active?: boolean
   description: string
   icon?: React.ReactNode
-}> = ({ active, description, icon, children, ...props }) => {
+}> = ({ children, ...props }) => {
   const classes = useStyles()
+  const active = false
+  const icon: React.ReactNode = null
+  const description = ''
   return (
     <Card {...props} className={clsx(classes.root)} variant="outlined">

Removing CardProps & from FC is almost the same result. Perhaps it is because CardProps extends PaperProps, which extends the large HTMLAttributes.

UPDATE & IMPORTANT: It turned out that replacing CardProps with HTMLAttributes<HTMLDivElement> also reduces time (not measured).

ypresto commented 4 years ago

Finally, I found the biggest one, 750ms → 130ms:

Removing style={...} from two Typographys.

-<Typography variant="subtitle2" component="div" noWrap style={{ width: '26ch' }}>...</Typography>
+<Typography variant="subtitle2" component="div" noWrap>...</Typography>
-<Typography variant="caption" component="div" noWrap style={{ width: '20ch' }}>...</Typography>
+<Typography variant="caption" component="div" noWrap>...</Typography>

But why? Adding the same style to <div> does not hit the performance. Maybe OverridableComponent is too complicated..?

(I'm using TypeScript 3.8.3, @material-ui/core 4.9.1)

embeddedt commented 4 years ago

AFAIK the way Material-UI handles local styles on components is different than the way React handles it for HTML elements.

ypresto commented 4 years ago

@embeddedt In type level, it resolves to React.CSSProperties which is the same as div's style prop.

embeddedt commented 4 years ago

@ypresto I stand corrected. Sorry.

eric-burel commented 4 years ago

Hi guys, not sure if it's worth opening a new issue for this, so I'll post it here since it's related to types correctness/performance. Let me know if I should open an issue instead. When following the documentation to add a custom font, I end up with the following typing error: Type 'string' is not assignable to type 'FontFaceFontDisplayProperty'

It's weird, because csstype 2.6.9 typings seems valid and other attributes are ok (using MUI 4.9.5).

const sourceSansPro = {
  fontFamily: "'Source Sans Pro'",
  fontStyle: "normal",
  fontDisplay: "swap", // won't work
  fontWeight: 400,
  src: `
    url('/static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf') format("truetype")
  `
};

Theme property:

  overrides: {
    MuiCssBaseline: {
      "@global": {
        "@font-face": [sourceSansPro]
      }
    }

Type is type FontFaceFontDisplayProperty = "auto" | "block" | "fallback" | "optional" | "swap";

eps1lon commented 4 years ago

@eric-burel This is an isssue with typescripts' automatic type widening. Try

- fontDisplay: "swap", // won't work
+ fontDisplay: "swap" as "swap",
eric-burel commented 4 years ago

Thanks it works, and I've learnt a new concept "type widening" :) It's weird that fontStyle is not affected for example, it's not the only CSS property defined as an enum but the first time I hit this.

Edit: ok my bad it is well documented: https://material-ui.com/guides/typescript/#using-createstyles-to-defeat-type-widening

yatrix7 commented 4 years ago

Finally, I found the biggest one, 750ms → 130ms:

Removing style={...} from two Typographys.

-<Typography variant="subtitle2" component="div" noWrap style={{ width: '26ch' }}>...</Typography>
+<Typography variant="subtitle2" component="div" noWrap>...</Typography>
-<Typography variant="caption" component="div" noWrap style={{ width: '20ch' }}>...</Typography>
+<Typography variant="caption" component="div" noWrap>...</Typography>

But why? Adding the same style to <div> does not hit the performance. Maybe OverridableComponent is too complicated..?

(I'm using TypeScript 3.8.3, @material-ui/core 4.9.1)

Have you found this to affect build time, or just the time it takes for intellisense to be useful? I'm getting the build issue (out of memory) and some of our TS code has a ton of style={someStyle} set on the components. Wondering if that's part of our issue.

amcasey commented 4 years ago

@yatrix7, generally speaking, I'd expect these long check times to affect both build and editor response times.

FabianSellmann commented 3 years ago

I anyone currently looking into this? I know there have been some improvements in regards to typescript type checking time in previous version upgrades. However, it is still slow. Would not mind looking into this myself.

eps1lon commented 3 years ago

Would not mind looking into this myself.

That'd be awesome. We're currently not aware of actionable items for us to work on. So any pointers to bottlenecks would be appreciated.

FabianSellmann commented 3 years ago

Added some benchmarking for now, to help investigate: https://github.com/mui-org/material-ui/pull/22110

amcasey commented 3 years ago

@FabianKielmann On the TS end, I've been working on perf investigation tools that I hope will soon be mature enough apply to material-ui.

If you have some time to spend on this, you might also try something like https://github.com/microsoft/TypeScript/issues/38583.

ypresto commented 2 years ago

The last few days, I was investigating on OverridableComponent and makeStyles/createStyles performance and type inference implementation (checker.ts in TS).

I found the cause of VSCode response time breaks up to two groups (of language server methods):

Latter means, if you have at least one huge type check hotspot in anywhere in opened files, you will see long response time on edit. So resolving this also improves completion experience.

EDITED: Every time you edit file tsserver clears cached types. When the first call to one of above commands is triggered after edit, it instantiates types if necessary.

Currently in fresh environment only with typescript and material-ui <Button | completion takes almost 1 sec. If you have makeStyles(theme => createStyles(...)) in editing file it takes around 300ms for highlights and diagnostics, and warms your CPU.

For OverridableComponent performance I'm still finding stable solution for now (could be resolved with below solution when without component="..." and type error in editing file).


I found an easy solution for makeStyles/createStyles one: just add overload for static version.

In my understanding (by JS profiling), currently createStyles and makeStyles are slow (in fresh environment by below reasons:

But majority of makeStyles() usages should be static, also dynamic css have overhead on JSS side, shortcut path to it would resolve most of makeStyles performance issue. Because chooseOverload in checker.ts will try top to bottom order, we can place static version signature first to skip instantiating the huge.

export default function createStyles<ClassKey extends string>(
  styles: StaticStyleRules<ClassKey>
): StaticStyleRules<ClassKey>;
export default function createStyles<ClassKey extends string, Props extends {}>(
  styles: StyleRules<Props, ClassKey>
): StyleRules<Props, ClassKey>;

export type StaticStyleRules<ClassKey extends string = string> = Record<ClassKey, CSSProperties>

Static version signature is also necessary for makeStyles().

This solution does not reduce check time while typing with type error. Providing createStaticStyles-like function can solve it but users should use two kinds of createStyles function.

Profiling result

Using this extension (sets TSS_DEBUG) and chrome://inspect. In my current production project folder.

Trigger semantic highlights and diagnostics by adding a few space characters at the end of this file:

import { createStyles, makeStyles } from '@material-ui/core'

const useStyles = makeStyles(theme => createStyles({ root: { width: 100 } }))

Package versions:

Results: (159.1 + 184.4 ms -> 7.1ms + 12.9ms)

Before getDiagnostics: 159.1 ms getEncodedSemanticClassifications: 184.4 ms
After getDiagnostics: 7.1 ms getEncodedSemanticClassifications: 12.9ms
eps1lon commented 2 years ago

@ypresto Great analysis!

Would love to get this in for makeStyles

Though our general effort shifted away from makeStyles to our new styled function. Would be nice to know if this function also has similar performance problems and if we can apply a similar fix.

ypresto commented 2 years ago

styled(Component)(styles) has two part of type inference: styled(Component) and componentCreator(style). Former must have difficulties around component props, so I tried from latter first.

import { CreateStyledComponent } from "@material-ui/system";

type Foo = CreateStyledComponent<
    {},
    JSX.IntrinsicElements['a']
  >
export const foo: Foo = (() => {}) as any
import {foo} from './above-file'

const Component = foo({ width: 100 })
baseline: 170-210 ms getDiagnostics(): 177.5 ms

The ground rule is: avoid instantiation (apply type parameter or reduce union or etc., e.g. to get properties) of type with huge keys.

Reduce union length of InterpolationPrimitive: <= 20 ms getDiagnostics(): 17.8 ms
export type InterpolationPrimitive =
  // | null
  // | undefined
  // | boolean
  // | number
  // | string
  | ComponentSelector
  | Keyframes
  | SerializedStyles
  | CSSObject;

It is quite surprising. Reason of this is in TS code of the hotspot getKeyPropertyName().

getKeyPropertyName() takes most of getDiagnostics() time (This perhaps from another profiling result, others must not be just 7ms :joy:) getKeyPropertyName() costs around 170ms
        // Return the name of a discriminant property for which it was possible and feasible to construct a map of
        // constituent types keyed by the literal types of the property by that name in each constituent type.
        function getKeyPropertyName(unionType: UnionType): __String | undefined {
            const types = unionType.types;
            // We only construct maps for large unions with non-primitive constituents.
            if (types.length < 10 || getObjectFlags(unionType) & ObjectFlags.PrimitiveUnion) {
                return undefined;
            }
            if (unionType.keyPropertyName === undefined) {

And our union type has 11 items for export type Interpolation<Props> (9 + 2), but half of them are just primitives. This TS code seems to be an optimization, but it taking much more than just return undefined. This should be fixed in TypeScript-side somehow, but perhaps we can workaround for it by removing items not required (possibly primitive values are covered by CSSObject?).

If we cannot avoid instantiation, below one might help:

No multi values: around 100 ms getDiagnostics(): 105.6 ms
-export interface CSSObject extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObject {}
+export interface CSSObject extends CSSProperties, CSSPseudos, CSSOthersObject {}

CSSPropertiesWithMultiValues will iterate through all CSS property names, so it is slow on instantiation. This is a big one, but is incompatible with original typing and still slow. We should avoid instantiation itself if possible.


const Component = styled('a')(({ theme }) => ({ width: 100 })) still consumes 500-600ms. Adding static version overload solves it to 50ms.

interface StaticFunctionInterpolation {
  (props: { theme: DefaultTheme }): CSSInterpolation;
}

export interface CreateStyledComponent<
  ComponentProps extends {},
  SpecificComponentProps extends {} = {},
  JSXProps extends {} = {},
> {
  (
    ...styles: Array<
      InterpolationPrimitive | StaticFunctionInterpolation
    >
  ): StyledComponent<ComponentProps, SpecificComponentProps, JSXProps>;

  ... (rest of overloads) ...
}

But interestingly, removing sx from CreateStyledComponent instead of above solves it too.

  <Tag extends keyof JSX.IntrinsicElements>(
    tag: Tag,
    options?: StyledOptions & MuiStyledOptions,
  ): CreateStyledComponent<
    {
      theme?: Theme;
      as?: React.ElementType;
      sx?: SxProps<Theme>;
    },
    JSX.IntrinsicElements[Tag]
  >;

styled(Button) version still relatively slow (180ms) so I'll investigate on that and SxProps.


@material-ui/system seems coping emotion's interface, but it would be better to be simplified to really needed features for future performance? (I also think compatibility is important)

ypresto commented 2 years ago

From my another investigation, OverridableComponent is very, very slow (1sec in my 16inch MBP). It eagerly resolves ComponentProps<React.ElementType> with/without component="...", and currently no perfect solution without improving type inference in TS compiler. If we can replace that of non-styled components with withComponent() (i.e. remove component prop), it might be an escape hatch from 1sec-on-every-type hell.

eps1lon commented 2 years ago

This sounds all reasonable to me. I just don't have time to apply this myself since it'll take time to get into. @ypresto Would be awesome if you could work on a PR so that we can check integration (performance).

RileyMShea commented 2 years ago

Am I correct in thinking that the bulk of the slowness comes from the styling theme types, and if I avoid using the context provider, just sticking with @materialui-core I won't see such a huge slowdown?

I hate to be overly dramatic since I'm sure a lot of work has gone into v5.0 but I cloned the nextjs-typescript v5beta2 example and @ypresto 's description of 1sec-on-every-type hell sums up my experience exactly. The completion speed is about on par with v4 from when I used it a year ago. Using the nightly typescript extension that brings the TS v4.4 perf improvements in vscode seems to help a bit but I don't have any hard numbers to back that.

embeddedt commented 2 years ago

@ypresto I am sure you are a lot more knowledgeable about this than I am. Is there a way for me to blacklist all of the expensive/complex types from @material-ui/core from being used for typechecking (i.e. replace them with any)? I use Material UI v4 in a production app, and the slow typechecking speed is quite annoying. I'd happily sacrifice type accuracy on the CSS-in-JS objects.

I'm personally finding that it takes upwards of 5-10 seconds for IntelliSense to finish reparsing code after I type anything, which leads to a lot of time waiting for red squiggles to appear in the right location. It sounds like v5 did not make any major improvements in this regard.

I've been using the nightly TypeScript extension for at least a year, so unfortunately that won't help me.

ypresto commented 2 years ago

@RileyMShea

1sec-on-every-type hell sums up my experience exactly.

Where do you experience it? If you don't have any styled() or makeStyles() in the file, perhaps it is caused by components which support component="..." prop. It is OverridableComponent one, and not styling nor theme type. ThemeProvider itself do nothing about type performance at least until you opens file which renders ThemeProvider.

RileyMShea commented 2 years ago

@ypresto I was in a fresh copy of https://github.com/mui-org/material-ui/blob/next/examples/nextjs-with-typescript/pages/about.tsx added a Button and tried getting autocomplete on the variant prop.

// Slow completion here 
<Button variant="...">sample</Button>

If I understand correctly, because ButtonBase supports the component prop, that might make autocomplete slow, even though I'm not making use of the component prop in this instance.

I am not sure if it makes a difference but I let vscode auto-import Button for me, which opted to use the default export instead of the named export. I remember some performance issues with certain bundlers/starup-times depending on how things were imported, but I(perhaps erroneously) assumed that wasn't relevant to TS completion speed.

ypresto commented 2 years ago

@embeddedt @RileyMShea

If you want a temporary patch to speed up (while it is not very good solution, you warned, and also have limitation), here is the one for material-ui v4. You can apply these (by hand) to your files under node_modules.

EDIT: Also place below in withStyles.d.ts.

export type StaticStyleRules<ClassKey extends string = string> = Record<ClassKey, CSSProperties>;

export type StaticStyleRulesCallback<Theme, ClassKey extends string = string> = (
  theme: Theme,
) => StaticStyleRules<ClassKey>;

export type StaticStyles<Theme, ClassKey extends string = string> =
  | StaticStyleRules<ClassKey>
  | StaticStyleRulesCallback<Theme, ClassKey>;

@material-ui/styles/createStyles/createStyles.d.ts

 // and https://github.com/microsoft/TypeScript/issues/31735
+export default function createStyles<ClassKey extends string>(
+  styles: StaticStyleRules<ClassKey>
+): StaticStyleRules<ClassKey>;
 export default function createStyles<ClassKey extends string, Props extends {}>(

@material-ui/core/styles/makeStyles.d.ts

+export default function makeStyles<
+  Theme = DefaultTheme,
+  ClassKey extends string = string
+>(
+  styles: StaticStyles<Theme, ClassKey>,
+  options?: Omit<WithStylesOptions<Theme>, 'withTheme'>
+): (props?: any) => ClassNameMap<ClassKey>;
 export default function makeStyles<

@material-ui/core/OverridableComponent.d.ts

 export interface OverridableComponent<M extends OverridableTypeMap> {
+  (props: DefaultComponentProps<M>): JSX.Element;
   <C extends React.ElementType>(

@types/react/index.d.ts

 type LibraryManagedAttributes<C, P> =
+  Pick<C, keyof C> extends Pick<React.ExoticComponent, keyof React.ExoticComponent> ?
     C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
       ? T extends React.MemoExoticComponent<infer U> | React.LazyExoticComponent<infer U>
         ? ReactManagedAttributes<U, P>
         : ReactManagedAttributes<T, P>
       : ReactManagedAttributes<C, P>
+    : ReactManagedAttributes<C, P>;

Limitation here is: if you write component="..." in your code it would be slow.

@types/react one have long description, I'll write it (and PR) later.

ypresto commented 2 years ago

For union length of Interpolation primitive, we should count up actual length to determine how many we should remove item from it.

export interface CSSOthersObject {
  [propertiesName: string]: unknown | CSSInterpolation; // length: 12
}

export type CSSInterpolation = InterpolationPrimitive | ArrayCSSInterpolation; // length: 11

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>;

As TypeScript limits fast path to 9 items at the most, we have to remove 3 items in union to reduce 200ms to 40-50ms. But it will break current typing, so I'll send issue/PR to TypeScript itself.

juanrgm commented 2 years ago

I replaced all type objects at node_modules\csstype\index.d.ts by any but checking time keeps between 3 and 4 seconds simply with a Button component.

ypresto commented 2 years ago

@juanrgm Button is slow on edit because of JSX.IntrinsicElements, not csstype.

Please refer https://github.com/mui-org/material-ui/issues/19113#issuecomment-883562019 for workaround.

juanrgm commented 2 years ago

@juanrgm Button is slow on edit because of JSX.IntrinsicElements, not csstype.

Please refer #19113 (comment) for workaround.

I am using material 5, not 4, but thanks for the tip.

After of leave only 5 tags at JSX.IntrinsicElements the check time fell to 2 seconds.

ChuckJonas commented 2 years ago

Has there been any progress on this? Material-UI v5 is borderline unusable due to this.

Nekonyx commented 2 years ago

Has there been any progress on this? Material-UI v5 is borderline unusable due to this.

Try to do it yourself. This is Open Source. I've been following this Issue for quite some time, and things are moving very slowly, so I don't think anyone will take care of it.

ChuckJonas commented 2 years ago

@Nekonyx k, fill me in on the effort you've made and I'll see if I can move the needle.

I was just asking because there hasn't been an update since October and this is probably the most compelling reason to move away from MUI I've seen.

Doesn't seem like it's a concern for the contributors so I'm sincerely wondering if it's not an issue they themselves face?

Every change takes 4-10s to complete types checks and it's not like I'm working on a potato (2018 MBP 2.9 Intel I9 w/ 32gb of ram). If others aren't experiencing the same, then maybe it's a problem with my configuration

nfour commented 2 years ago

I was wondering if anyone had thought of having different type distributions for MUI.

So assuming the sx property is the culprit, but lets just use it as an example...

https://mui.com/system/the-sx-prop/

I don't need to use the sx prop when I use MUI because instead I utilize this pattern from emotion/styled-components:

<Button css={css`
  color: ${(p) => p.theme.palette.primary};
`}>

I think this is pretty standard these days too and wouldn't be too wild to justify.

Some ideas:

ChuckJonas commented 2 years ago

I've noticed the biggest offender in my project is using @mui/system/styled.

If I wrap an mui component (EG button), my typescript hangs for 30+ s. I actually had to increase the memory limit to even get it to finish typecheck without blowing the heap.

Meligy commented 2 years ago

Just for the team visibility, this continues to be an issue for many developers, and the team might not see that because most of the noise is happening in TypeScript's own repository:

https://github.com/microsoft/TypeScript/issues/34801

And a member of the TypeScript has just used a comment from 2020 in this thread above to say it seems material-ui is not interested in more improvement, and another comment here from last year saying it's not a priority to you in their last comment on the TypeScript thread. I'm hoping this is no longer the case, although I understand and appreciate the nature of volunteer work and appreciate the free goodness (I wish I could have pointers to try to help myself).

At this stage I've been working with material-ui for several months. I've had a few issues here and there and they are all workable. This particular one has been quite a headache for my team though and I can imagine it being a reason not to choose material-ui in the future (not a strong reason but a candidate). Especially now that TypeScript is becoming more widely used in react projects.

embeddedt commented 2 years ago

At this point, I often just try to disable MUI types as much as possible in my codebase to prevent autocompletion lag.

oliviertassinari commented 2 years ago

88 upvotes on this comment: https://www.reddit.com/r/reactjs/comments/sbrjxs/choosing_the_right_component_library_for_your/hu1tqmy/

MUI with typescript is a nightmare right now. It literally takes more than 3-4 seconds for autocomplete or IntelliSense to show up. And this problem has not been solved since 2019.

We need to change something.

siriwatknp commented 2 years ago

@amcasey @michaldudak I would like to help identify the bottleneck so that we can see what options we have to improve the performance. I am pretty new to profiling the typescript performance (not even sure I use the right word), so can you guide the way, tool to be used to find the bottleneck? Thanks.

My thought is that if we have a typescript performance report in each PR, that'd be awesome.

s97712 commented 2 years ago

node_modules/@mui/material/OverridableComponent.d.ts

export type OverrideProps<
  M extends OverridableTypeMap,
  C extends React.ElementType
> = (
  & BaseProps<M>
-  & DistributiveOmit<React.ComponentPropsWithRef<C>, keyof BaseProps<M>>
+  & DistributiveOmit<React.ComponentProps<C>, keyof BaseProps<M>>
);

By elimination, I found that removing `WithRef' can significantly improve performance

stylemate commented 2 years ago

@s97712 lol, this works. Is there any side effect to this?

s97712 commented 2 years ago

@s97712 lol, this works. Is there any side effect to this?

If the component prop is not used, there is no effect

enoh-barbu commented 2 years ago

yes there is, IDE will not suggest properly in all cases, was tested by me

da1z commented 2 years ago

Is there workaround for v5?

douglasg14b commented 2 years ago

Is this why vscode is unbearably slow with when on projects with MUI?

Intellisense takes seconds to pop up, and type errors sometimes take 10+ seconds to go away.

It's pretty ridiculous.

embeddedt commented 2 years ago

@douglasg14b Yes, TypeScript seems to be the main issue, sadly. If you don't care about typings, the hack I found was to just remove the typing files for MUI entirely from node_modules. The issue is that you don't get any completion at all after that change. Ideally this needs to be fixed on the MUI side. I think many of us (including myself) would be happy to provide profiling data/other help if guided.