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

Typescript pulls entire MUI library - super slow type checking #25085

Closed
rpmonteiro opened this issue Jun 20, 2018 · 12 comments · Fixed by #25302
Closed

Typescript pulls entire MUI library - super slow type checking #25085

rpmonteiro opened this issue Jun 20, 2018 · 12 comments · Fixed by #25302
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue High Priority

Comments

@rpmonteiro
Copy link

rpmonteiro commented Jun 20, 2018

TypeScript Version: 2.9.2

Search Terms:
MUI slow typescript
TSC compiles all MUI files

Code

In a react project, I use the UI library MUI (1.0).
In total, I'm doing around 15 imports of this library, always in the following way:
import CircularProgress from '@material-ui/core/CircularProgress/CircularProgress';

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./src",
    "outDir": "build/dist",
    "target": "es5",
    "lib": ["es6", "es7", "dom"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "rootDir": "./src",
    "noEmitOnError": false,
    "isolatedModules": true,
    "strictPropertyInitialization": false,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "noErrorTruncation": true,
    "noImplicitReturns": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "diagnostics": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "dist",
    "build",
    "node_modules",
    "src/**/__tests__"
  ],
  "defaultSeverity": "warning"
}

Expected behavior:
TS picks up only the type definitions it needs from that library. (around 20 files, as I counted)
Code compiles in 3-6 seconds, if I remove MUI (with lots of errors, certainly)
image

Actual behavior:
TS pulls the entire MUI library, with over 600.000 types
Compilation (type checking) usually takes >1min
image
tsc --extendedDiagnostics --listFiles --noEmit
image

and it goes on...

I would expect this to happen if I was importing from the core modules, which exports all types, but I am most definitely not.

Related Issues:
No :( I found other cases of slow compilation, but not of this sort.

@AnyhowStep
Copy link
Contributor

It's possible that the package, or one of the packages it depends on, has a type declaration that is causing this slowness.

If you look at issue 24435, you'll see that it's possible to get check times of 497.42s or more. Sometimes never terminating, or running out of memory (I have this problem regularly).

It may be that the type is too complicated, or that the way it is written could be simplified.

I'm not 100% sure it's the cause of your problems but it may be worth investigating.

@rpmonteiro
Copy link
Author

Thank you, that gives me a couple ideas how to try and debug this. I'll do it soon and report my findings here

@mhegazy mhegazy added this to the TypeScript 3.0 milestone Jun 21, 2018
@mhegazy mhegazy added Bug A bug in TypeScript High Priority Needs Investigation This issue needs a team member to investigate its status. labels Jun 21, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Jun 21, 2018

@weswigham can you take a look at the library and see what is causing the perf issues?

@weswigham
Copy link
Member

@rpmonteiro do you have a list of the material-ui components you use? CircularProgress alone doesn't seem to significantly impact build times at all.

@rpmonteiro
Copy link
Author

rpmonteiro commented Jun 25, 2018

here are the imports being used, both for types, and components:

type imports

import { PopoverActions } from '@material-ui/core/Popover';
import { WithStyles, StyledComponentProps } from '@material-ui/core/styles';
import { GridSpacing, GridJustification, GridSize } from '@material-ui/core/Grid';
import { ButtonProps } from '@material-ui/core/Button';

component/method imports

import createStyles from '@material-ui/core/styles/createStyles';
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
import withStyles from '@material-ui/core/styles/withStyles';

import Button from '@material-ui/core/Button';
import CircularProgress from '@material-ui/core/CircularProgress';
import Typography from '@material-ui/core/Typography/Typography';
import Hidden from '@material-ui/core/Hidden';
import Card from '@material-ui/core/Card';

import Grid from '@material-ui/core/Grid';
import TextField from '@material-ui/core/TextField';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import CardContent from '@material-ui/core/CardContent';

import Checkbox from '@material-ui/core/Checkbox';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import ListItem from '@material-ui/core/ListItem';
import Snackbar from '@material-ui/core/Snackbar';
import IconButton from '@material-ui/core/IconButton';

import Paper from '@material-ui/core/Paper';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import ExpansionPanel from '@material-ui/core/ExpansionPanel';

import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
import Tooltip from '@material-ui/core/Tooltip';

@weswigham
Copy link
Member

import withStyles from '@material-ui/core/styles/withStyles';

points at withStyles.d.ts, which contains

import { ConsistentWith, Overwrite } from '..';

that .. is a reference to the top-level index.d.ts in @material-ui/core that imports everything, which would likely be why the file count goes up so much with so few imports; I wouldn't be surprised if that root import shows up in a few other places in material-ui, too, since they stashed some util types in the root index.d.ts.

BUT! The the inclusion of all those files is likely not itself what's making your build so slow (yes, it's more work than it should need to do, but not 50s of work, more like 1s) - somewhere where you're actually using @material-ui (eg, a tag), you're triggering some kind of catastropic worst-case typechecking scenario, since if you have just a file with those imports that does nothing real:

import * as React from "react";

import createStyles from '@material-ui/core/styles/createStyles';
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
import withStyles from '@material-ui/core/styles/withStyles';

import Button from '@material-ui/core/Button';
import CircularProgress from '@material-ui/core/CircularProgress';
import Typography from '@material-ui/core/Typography/Typography';
import Hidden from '@material-ui/core/Hidden';
import Card from '@material-ui/core/Card';

import Grid from '@material-ui/core/Grid';
import TextField from '@material-ui/core/TextField';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import CardContent from '@material-ui/core/CardContent';

import Checkbox from '@material-ui/core/Checkbox';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import ListItem from '@material-ui/core/ListItem';
import Snackbar from '@material-ui/core/Snackbar';
import IconButton from '@material-ui/core/IconButton';

import Paper from '@material-ui/core/Paper';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import ExpansionPanel from '@material-ui/core/ExpansionPanel';

import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
import Tooltip from '@material-ui/core/Tooltip';

import Popover, { PopoverActions } from '@material-ui/core/Popover';
import { WithStyles, StyledComponentProps } from '@material-ui/core/styles';
import { GridSpacing, GridJustification, GridSize } from '@material-ui/core/Grid';
import { ButtonProps } from '@material-ui/core/Button';

void createStyles, createMuiTheme, withStyles, Button, CircularProgress, Typography, Hidden, Card, Grid, TextField,
    AppBar, Toolbar, CardContent, Checkbox, FormControlLabel, ListItem, Snackbar, IconButton, Paper, Dialog, DialogContent,
    DialogActions, ExpansionPanel, ExpansionPanelSummary, ExpansionPanelDetails, Tooltip, Popover, React;

declare var x: PopoverActions;
declare var y: WithStyles;
declare var z: StyledComponentProps;
declare var a: GridSpacing;
declare var b: GridJustification;
declare var c: GridSize;
declare var d: ButtonProps;

void x,y,z,a,b,c,d;

the project compiles in around a second. That bears out in the type count, too -
image
That's nowheres near the more concerning 600k types you report. So while @material-ui likely participates in the types which are causing this problem, it alone is not the problem. Could you share a more detailed repro?

My intuition is to look around the code where you use withStyles, since that has a relatively complex type itself (and so is more likely to interact poorly with something else complex and create a explosion like this); but that's just a gut feeling and without knowing more, the problem could be almost anywhere.

@rpmonteiro
Copy link
Author

Thank you for your comprehensive reply!! I'm going to do as you suggest, and report my findings ASAP. Thanks again

@rpmonteiro
Copy link
Author

rpmonteiro commented Jun 27, 2018

Ok, I already made a significant discovery.

There are 81 imports of the Grid component in the app.

import Grid from '@material-ui/core/Grid/Grid';

Also tried changing the import to the following, but with the same results:

import Grid from '@material-ui/core/Grid';

Results of commenting all those Grid imports out:
Before
image
After
image

And after commenting out all imports from that library:
image

@weswigham
Copy link
Member

Alright... I think Grid is a generic component (iirc); what do your usages of Grid look like?

@rpmonteiro
Copy link
Author

Like the following:
image

Sometimes there are more complex layouts with 3 or 4 nested Grid components

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Jun 27, 2018

We found a similar repro from Developer Community (slow checking with MUI, seems to use Grid a lot as well) and will be investigating from that one - almost certainly the root cause is the same. Thanks for the help so far!

@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Jun 28, 2018
@rpmonteiro
Copy link
Author

Amazing! The entire team and I are very happy with the once again blazing fast performance. Thank you, guys!!

@mhegazy mhegazy removed the Needs Investigation This issue needs a team member to investigate its status. label Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue High Priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants