Skip to content
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

Type checking/VS Code slow when using MUI #34801

Closed
jdoklovic opened this issue Oct 29, 2019 · 130 comments
Closed

Type checking/VS Code slow when using MUI #34801

jdoklovic opened this issue Oct 29, 2019 · 130 comments
Labels
External Relates to another program, environment, or user action which we cannot control.

Comments

@jdoklovic
Copy link

TypeScript Version: 3.8.0-dev.20191029

Search Terms: mui, material-ui, typescript, slow

Example Project
https://github.com/jdoklovic/mui-slowness

Expected behavior: Make a bad change to something in src/react/pages/Main.tsx autocomplete seems to be speedy, and error reporting should be too.

Actual behavior: Takes forever to see errors

Related Issues: #32085, #32229, #31817, #30908

Not exactly sure what's going on, but the error reporting in VS Code is super slow.
I've made sure I'm using specific named imports, and I've even forked MUI and mad all of the internal code so the same and removed things like import from '..' but it didn't seem to help.

Here's the output from tsserver logs which doesn't seem to contain anything that jumps out at me.
Also note, I'm using typescript-eslint with the VS Code ESLint extension, not tslint, but eslint seems to be pretty fast.

mui-slowness-tsserver.log

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Oct 30, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.8.0 milestone Oct 30, 2019
@amcasey amcasey added the Domain: Performance Reports of unusually slow behavior label Oct 30, 2019
@amcasey
Copy link
Member

amcasey commented Oct 30, 2019

First off, this bug report is just about perfect, so thanks for that! Second, skipLibCheck usually helps, but you've already got that. Anyone else reading this might want to give that a shot.

I'll look for possible improvements in both TS and the MUI type decls. Thanks!

@jdoklovic
Copy link
Author

Thanks @amcasey. Let me know if you need any other data/log dumps or whatever.
Also, I hsould mention that if I launch the app with webpack-dev-server --open --config webpack.react.webview.js the VS Code editor is still super slow to report errors, but if I make a change and save, the watch process/compilation is super fast and usually completes and reloads the browser before VS Code catches up. Not sure if that's useful info or not.

@amcasey
Copy link
Member

amcasey commented Nov 1, 2019

The issue we usually see with responsiveness in MUI consumers is with the large number of icon types. In this case, however, it appears that MUI is using some complicated conditional types to provide sophisticated checking of API usage. I'm experimenting with both tweaking their types and improving compiler perf, but, so far, the solution isn't obvious.

@zaguiini
Copy link

zaguiini commented Nov 8, 2019

It's not just errors... Any changes takes enormous time to be processed.

@dcworldwide
Copy link

dcworldwide commented Nov 9, 2019

I am in compilation hell. 300% CPU and my machine is bricked for 15 minutes.

"@material-ui/core": "^4.3.3",
"@material-ui/icons": "^4.2.1",
"@material-ui/pickers": "^3.2.4",
"@material-ui/styles": "^4.3.3",

"typescript": "^3.7.2",

@Ravnurin
Copy link

Ravnurin commented Dec 9, 2019

TSC is still incredibly, frustratingly slow for me in any files using MUI. Typically takes anywhere between 5 to 10 seconds from making a change to the type checking to finish and errors being flagged.

When I first open VSC and start the build process, it seems sometimes type checking is relatively fast (1-2 seconds), but becomes slower over time (eventually hitting 5-10 secs). Other times, however, it seems it's also the amount of MUI components used in the working file that impacts TSC speeds.

I remember about 5 months ago I found using specifically TypeScript version 3.3.4000 to actually resolve the slow TSC issues, whereas the following versions were all affected by this slowness. Not tested it since though.

@AlCalzone
Copy link
Contributor

In a small project of mine, I've started to have a watch process with noEmit specifically for *.tsx files. This gives significantly faster feedback (4-5 seconds) if something broke than IntelliSense, which takes forever to update.

@amcasey
Copy link
Member

amcasey commented Dec 9, 2019

Unfortunately, I have yet to find either a solution or a mitigation. I'm reluctant to push a totally new strategy onto the MUI type authors and finding a smaller change with the same effect is much more difficult. Obviously, you do have the option of not using @types/material-ui, but that will make completion a lot less useful and error detection a lot less thorough.

@amcasey
Copy link
Member

amcasey commented Dec 9, 2019

@rrebase @Ravnurin @AlCalzone Having additional (ideally, small) repros would help with this one. Is your code shareable?

@amcasey
Copy link
Member

amcasey commented Dec 10, 2019

I decided to start over with a clean version of @jdoklovic's repro and now I'm seeing a ~3 second delay on startup and then good responsiveness after that (there's a ~2 second lag for squiggles, but that's by design, so they don't flicker, etc). I'm on VS Code 1.40.2 and TS 2.8.0-dev.20191207. I'll try to figure out where those 3 seconds are going, but they're a lot less worrisome than the 12 seconds in the original report.

If people are still seeing longer delays, additional repros would be very helpful. Also, consider giving TS 3.7 a shot, since we made a bunch of perf fixes.

@AlCalzone
Copy link
Contributor

Is your code shareable?

I can email you an archive with the repo in it if that is okay. It currently consists of about 23 TSX and 32 TS files that are relevant to the frontend where I'm seeing the delays. I'll see if I can reduce the size or at least give you some steps how to trigger the longer delays.

@amcasey
Copy link
Member

amcasey commented Dec 10, 2019

@AlCalzone Sure. [email protected]

Edit: Please let me know when you do this, since external mail with attached JS is pretty likely to be flagged by IT.

@amcasey
Copy link
Member

amcasey commented Dec 10, 2019

I dug into the 3 second delay and, once again, signs point to And and IsEmptyInterface as the source of the slowdown (since they use complex conditional types that affect type inference). I previously made an attempt to simplify those types, but it had unexpected semantic ramifications and had to be reverted. I'll try again.

@AlCalzone
Copy link
Contributor

@amcasey I hope I find some time later today (CET). I'll let you know here when I send the mail.

@AlCalzone
Copy link
Contributor

@amcasey I sent you an email with the subject "Repro for MUI slowness (AlCalzone)"

@QingqiShi
Copy link

Unfortunately, I have yet to find either a solution or a mitigation. I'm reluctant to push a totally new strategy onto the MUI type authors and finding a smaller change with the same effect is much more difficult. Obviously, you do have the option of not using @types/material-ui, but that will make completion a lot less useful and error detection a lot less thorough.

Not sure if not using @types/material-ui is actually an option since material-ui has the types bundled with the package.

@amcasey
Copy link
Member

amcasey commented Dec 11, 2019

@AlCalzone Thanks! Found it in my spam folder. 😉

@amcasey
Copy link
Member

amcasey commented Dec 11, 2019

@QingqiShi You're quite right. We're usually dealing with typings from DefinitelyTyped and I got mixed up.

@AlCalzone
Copy link
Contributor

@amcasey I resent the mail with the extension changed to zip1 as suggested. If that doesn't work, let me know.

@Ravnurin
Copy link

@amcasey have you had a chance to look into the slowdown some more? I can appreciate it's probably one of those that'll take a fair bit of time to fix - If you need an additional sample repro let me know, happy to put something together.

@QingqiShi
Copy link

Here's something to try as a workaround if you have a beefy machine:

  • go to Settings in VSCode, and search for 'typescript memory', increase TypeScript › Tsserver: Max TS Server Memory to something like 8192.

I haven't had the opportunity to test this more extensively so if it works please let everyone know :)

@dcworldwide
Copy link

My memory was already maxed, so that didn't help me unfortunately.

@LonJonn
Copy link

LonJonn commented Jan 3, 2020

Same as me. I on a Macbook Pro 2017 (which should be capable enough) and having issues like extreme fan speeds and computer temps. Is there any update on this issue?

@amcasey
Copy link
Member

amcasey commented Jan 3, 2020

I've identified the slow part of the code in the repro that I have and it's complicated enough that compiling slowly seems justifiable, so my next step will be to determine whether the type definitions can be simplified. If that turns out not to be possible, I'll look for ways to speed up handling of this particular class of complex types.

@RyanCavanaugh
Copy link
Member

Seeing how that is one of the largest community projects with extensive type definitions I feel like the typescript project could help the community significantly by doing some further investigation

We've done this already (the linked issue was written by us); we had an engineer working on this problem full-time for over a month. We've also provided tools for analyzing performance. The material-ui maintainers have said they're not interested in simplifying further to make things more performant. We (and others) have identified problematic patterns and the material-ui maintainers have not taken it as a priority.

At the end of the day, we can't be in charge of making every project's types fast, especially if they are not hosting their types on DefinitelyTyped where the testing and updating process can be made faster. It's important that the TypeScript team spend time doing things that only we are capable of, and at this point, material-ui is fully capable of taking the advised trade-offs. They've chosen not to; it's their decision, and it's beyond our charter to spend a very constrained resource (engineer time) improving someone else's codebase, especially if they don't like the trade-offs that would be required to do those improvements.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Jan 12, 2022

I wanted to add more context -- if there are type system constructs we could add to TS to make material-ui's typings more performant, or if there are identified optimizations we could do to minimize the amount of work involved, we're super game. It sucks that things are slow! We'd like everything to be fast! But the current state of the world is that we've looked at material-ui as hard as we feasibly can, already done multiple fixes to improve things, and believe we're "stuck" given the way the typings are written and the sorts of patterns they want to represent.

material-ui is one of only 6 projects in our core performance suite, and we've more than once put pull requests on hold (example) because of perf issues specific to patterns it uses, so I don't want anyone to think we don't care about this project in particular - quite the opposite.

If I had to suggest a path forward for someone looking to make progress, it would be to start a "clean room" implementation of the material-ui types that handles their required use cases in a way that doesn't involve enormous type computations as a side effect. The maintainers of the project seem amenable to taking improvements and might be able to take a fresh start with better perf characteristics that still meets their use cases -- I'm not speaking for them, of course, but this seems like the best way to at least demonstrate that the things the library wants to represent don't require the large perf impact the current typings are incurring. If that demonstration ends up not being possible, then it becomes a good starting point for figuring out what kind of feature(s) TS would need to accomplish that.

@michaldudak
Copy link

Hi, I'm one of the core maintainers of MUI (formerly Material-UI).

We see that the problem of development-time performance is still present. As it was stated in the issues linked by @RyanCavanaugh, improving the performance of the existing code would require some tradeoffs and possibly breaking changes that we were not willing to make.

However, now we are able to make a fresh start, as we're sort of rebuilding the library. I lead the creation of the @mui/base package that will be a foundation of our new design system components (first) and the Material Design package (later). It's a great opportunity to improve the library and to take a second look at things we weren't able to do in the past.

We still have a long way to go but I wanted to assure you that we are aware of the problem and we'd like the developer experience to be great. I can't promise we'll get rid of every perf issue there is, but we'll work to make the library better.

@eps1lon
Copy link
Contributor

eps1lon commented Jan 13, 2022

The material-ui maintainers have said they're not interested in simplifying further to make things more performant

To be clear: "Simplifying" means removing type safety and auto-complete features. So it's not just simplifying at an internal level but actively stripping type features. Putting that entirely on us is a bit odd considering we're using features supported by TypeScript. If these cause performance issues then we could just as well turn around and say TypeScript should remove these features.

So yeah a fresh start would improve perf but stripping features always improves perf metrics. If you do less then you code runs faster. If you do more then your code runs slower.

What is really missing is an accurate and honest survey what people want. Because all we ever had is people saying "I want more type safety" or "I want faster type-checking". Both is simply not possible and not the problem of one side but both sides.

So far no concrete simplification was suggest that we can measure and then put on the chopping block asking "do people want this feature if it has a X% perf impact).

This was especially interesting since we had a simpler start with the new styled but we quickly received requests to improve type-safety/autocompletion that required more complex types.

I'm quite disappointed reading #34801 (comment). I was working on TypeScript and DefinitelyTyped integration as well for nearly 3 years. Oftentimes full time. When I was "not interested" I simply didn't have the time. But Microsoft is always welcome to fund these efforts. I can't tell you how much time I spend working on TypeScript and DT integration outside of Material-UI (oftentimes for perf issues) and hearing that I'm "not interested" is really discouraging.

@amcasey
Copy link
Member

amcasey commented Jan 13, 2022

Speaking as one of the main investigators on the TS side, I want to say that @eps1lon's help has been invaluable these last three years (on mui specifically and on DT in general) and I don't believe @RyanCavanaugh intended to convey otherwise. It's natural for hard problems like this to lead to differences of opinion (i.e. because there's no "best" trade-off) and we're all pretty frustrated by the obstacles we currently face, but I think we're unanimous in wanting the best dev experience.

p.s. @michaldudak I don't think we've worked together directly, but I appreciate the kind words.

@amcasey
Copy link
Member

amcasey commented Jan 13, 2022

I'm going to risk muddying the waters a bit by making a concrete proposal: I think that the holistic performance issue should be tracked on the MUI repo because TS just doesn't have the domain expertise to evaluate the correctness vs performance trade-offs for MUI developers; BUT specific issues should be filed here, including but not limited to:

  • The same code compiles more slowly in new TS than in old TS
  • An apparently trivial tweak to MUI results in a large perf change
  • MUI needs to express something that TS can't readily express (no promises)

@charrondev
Copy link

Is there a writeup anywhere for which types are features could be footguns re: performance?

When I was last investigating an issue with @emotion/css it had been due to a difference between using type NewType = MappingOf<VeryLargeType> vs interface NewType extends MappingOf<VeryLargeType> {}.

@samwightt
Copy link

@charrondev Not sure if this is what you're looking for, but the TypeScript GitHub wiki has a wonderful page on improving performance.

@samwightt
Copy link

samwightt commented Jan 13, 2022

Also just wanted to follow up and say that one of the biggest areas where I've seen a reduction in performance is with csstype. It seems like the further 'up' those types are (not nested in generics), the faster it is. So React's style prop might compute fairly quickly, but Chakra UI's CSS props or the styled props in MUI compute slower. Stitches is another example: it works fine with simple types, but as the theme object gets larger and the number of template strings it needs to generate gets larger, things get slower and slower. If you keep large interfaces out of generic types / as 'high' as possible, things seem to go faster.

So one thing that might help is 'hoisting' the csstype types up to a higher level? I haven't peeked at the MUI types since version 4, so I don't know how possible that would be. But maybe re-implementing emotion / styled-components types in a faster interface with fewer generics would speed things up.

Speaking on the type safety thing, I think a lot of developers confuse good editor autocomplete with type safety (see the Object.keys debate for more on this). Not saying that MUI is doing this, but I think a lot of projects end up adding more complicated types to improve autocomplete and developer experience. But those new types might not do a lot to catch bugs in production.

Example: Stitches' template string types are wonderful for autocomplete / DE. But they don't catch a lot of errors before they hit production. If you're using a $themeVariable inside a more complex expression (eg. calc()), that's not something the editor can autocomplete or that TypeScript can statically type. A more type-safe API would be an object with the theme variables on it, which the developer can embed using template strings (Vanilla Extract's API). It's a slight reduction in DE, but it'd be faster for TypeScript to compute and more type safe.

I don't know if something like this exists in the handbook already or not, but I think it might be useful for it to have a doc on designing APIs with the type system in mind. Complex types are wonderful, but I feel like they're better used for typing older, legacy APIs. If we can design APIs to be simpler and type safe, even if they reduce the developer experience a little, that might help a bit.

In addition it'd be nice for TypeScript to have debugging / profiling tools for types. It'd be great if I could see an actual trace of how TypeScript expands a type, or if I could see what took the longest. Ideally this would be something in VSCode (not a separate tool to install) cause I think it's something all TS developers could use.

@eps1lon
Copy link
Contributor

eps1lon commented Jan 17, 2022

I think that the holistic performance issue should be tracked on the MUI repo because TS just doesn't have the domain expertise to evaluate the correctness vs performance trade-offs for MUI developers; BUT specific issues should be filed here, including but not limited to:

Yep, I think this sums this up perfectly and concise. Ultimately we would have two versions we could publish: strict but slow and slow but fast. And then see what people prefer and which leads to better software.

Basically implement what tsconfig can do with its various strict configs at a library level.

Though this is ultimately a very hard and expensive task (for a developer). The main issue is that publishing looser types would almost never cause any failures because most users already have a passing typecheck. So we couldn't really rely on immediate community feedback. The library is usually the only location where both passing and failing typechecking is tested.

That's why I was saying that it would be really nice if somebody would spend some time by increasing performance and checking how much of our type test would started failing (considering we also assert on type-checking failures). Our type test suite is fairly extensive by now so I would hope it would help in tackling this issue. So far I've only seen analysis looking at performance improvements but not analysis looking at strictness/soundness.

So we will continue to track this inhttps://github.com/mui/material-ui/issues/19113. We still care about it (otherwise the issue wouldn't be open).

@amcasey
Copy link
Member

amcasey commented Jan 18, 2022

Ultimately we would have two versions we could publish

I love the idea of testing them side-by-side, but note that TypeScript doesn't (and won't soon) have a convenient way to associate more than one set of type definitions with a given import. At present, if you import a package and it has typings, they'll be used unconditionally (I'd love to know if someone has found a loophole that doesn't involve manipulating files under node_modules).

So we couldn't really rely on immediate community feedback

I'm not sure I understand your statement clearly, but I think we'll hear about it pretty quickly if people start getting a lot of runtime errors that the tooling should have caught.

So we will continue to track this inhttps://github.com/mui/material-ui/issues/19113. We still care about it (otherwise the issue wouldn't be open).

❤️

@landisdesign
Copy link

I came here through a Reddit post about Intellisense and MUI, and although it's not totally relevant to getting solutions, I wanted to say hats off to everyone here who's been working so hard and for so long to tackle this problem. When people have been earnestly struggling together for over two years to make things better for everyone out there, it needs to be acknowledged.

Thank you. Thank you. Thank you.

@casamia918
Copy link

Hi. I'm reporting my case, hope to be helpful to other one.

In briefly, I've subjected vscode intellisense performance issue, while using SxProps type.

But my performance issues is gone when I give Theme type parameter explicitly to SxProps, SxProps<Theme>.

In mui, they declare SxProps's generic type like this

export type SxProps<Theme extends object = {}> =
  | SystemStyleObject<Theme>
  | ((theme: Theme) => SystemStyleObject<Theme>)
  | Array<boolean | SystemStyleObject<Theme> | ((theme: Theme) => SystemStyleObject<Theme>)>;

package version
"@mui/material": "^5.3.1",
"@mui/styles": "^5.3.0",
"@mui/system": "^5.3.0",

This is detailed article.

https://gist.github.com/casamia918/dafd630a1cdd81935a4587297acaae00

@Rodrigo-JM
Copy link

I literally just had the same issue as @casamia918, and the fix actually works. Thank you!

@li1234yun
Copy link

Maybe typescript server needs to improve the complex project support capacity, because we can assume a project is typescript best practices.

@Taxi4you
Copy link

Taxi4you commented Apr 1, 2022

Still slow also for me, either JS or TS, plain project without anything installed.
Tried either:

import Button from '@mui/material/Button' or
import { Button } from '@mui/material'

How come that so common framework is just not functional in the most used IDE for JS and TS?

I have tried to exclude node_modules, both in tsconfig.json and settings.json still very slow..

Does someone know how to fix this one?

@enoh-barbu
Copy link

@Taxi4you nope, I got used with it, hopefully one day will be fixed :)

@angelvega93
Copy link

still very slow, almost unusable.

@Taxi4you
Copy link

Taxi4you commented Apr 3, 2022

@enoh-barbu One of the most popular frameworks on the probably most used language with the most used IDE, in 2022 and still doesn't work properly :/

@canIchangethispls
Copy link

Can confirm it is still extremely slow. Using skipLibCheck and increased typescript memory to ~16k does not seem to even remotely improve the situation.
I've tried other libraries and the difference is absolutely staggering, which leaves me with a difficult choice: Do I choose the extremely laggy, but more popular and more documented library, or a less documented counterpart?

I'm heavily leaning towards the latter which should be disappointing to hear.

@canIchangethispls
Copy link

canIchangethispls commented Jul 24, 2022

@Taxi4you nope, I got used with it, hopefully one day will be fixed :)

No way. I WILL choose another library over this issue. Taking over a second to autocomplete a very simple task annoys the crap out of me. I don't understand how anyone can cope with this in a high-pressure environment.

2022-07-24 14-59-00

newv

Another random library vs. MUI, this cannot be normal right? (right?)

@kpdecker
Copy link

Was just burned by this, with a single SxProps reference resulting in 10x time and memory usage (70s -> 7s, 4G+ -> 400M).

This eslint rule can be used to

    'no-restricted-syntax': [
      'error',
      {
        selector:
          'TSTypeReference[typeName.name="SxProps"]:not([typeParameters])',
        message:
          'SxProps must have Theme parameter to avoid significant compiler slowdown.',
      },
    ],

@tjx666
Copy link

tjx666 commented Jun 27, 2024

my explore and solution: https://github.com/tjx666/ts-perf-issue

@nbran
Copy link

nbran commented Jul 29, 2024

my explore and solution: https://github.com/tjx666/ts-perf-issue

Great tips. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Relates to another program, environment, or user action which we cannot control.
Projects
None yet
Development

No branches or pull requests