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

[core] Test some TypeScript perf optimizations #32571

Closed

Conversation

mnajdova
Copy link
Member

@mnajdova mnajdova commented May 3, 2022

TLDR

The optimization described below in Learnings won't make big difference in a bigger project, at least not based on the results of

yarn tsc --generateTrace

Even if we are not loading all types in the components themselves, there are likely going to be usages of createTheme where all component's props will anyway be loaded.

I am going to investigate next the type checking phase (this is likely where we can make significant improvements)

Summary

Just learning how to do performance tracing for TypeScript and trying some optimizations along the way. It's still too early to be reviewed, but if you know more about this, feel free to share your input.

I am starting by testing a default create-react-app using TypeScript where the App.tsx is defined as:

import * as React from 'react';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';

function App() {
  return (
    <div className="App">
      <Button variant='contained'>Button</Button>
      <Box sx={{ mt: 2, '& .some-class': { p: (theme) => theme.spacing(2) }}}>Box</Box>
    </div>
  );
}

export default App;

I've started by trying to optimize this part:

image

Note: Don't trust the number, I am just trying to see if I can get to pattern where Button.d.ts will be smaller than Box.d.ts.

This is how the chart looks with the build of the package in this PR:

image

It is visible that the Button.d.ts now takes much smaller part of the overall App.tsx compilation time.

When this change is propagated to the Box.d.ts too, the App.tsx is no longer the biggest chunk in the parent's time:

image

Questions

  • One thing I am not sure about is, whether there will be gains in improving the components' perf, if anyway in the project there is going to be used a createTheme and all types are anyway going to be loaded somewhere. Will this have effect in for example autocomplete of the component inside a file where none of the types from createTheme are being used?

Learnings

  • We are importing the Theme in each component's definition files, but the default Theme contains the components key which basically loads all components' props. We don't even need this key for the sx prop to work.
  • importing from an index.d.ts file is bad, as all types are being loaded, so I've tried to extract some types in a dedicated *.types.ts files so that they are not being defined and loaded from index. (not sure if I am correct about this one, but based on the numbers I saw it seems to be the case)

@mnajdova mnajdova added the proof of concept Studying and/or experimenting with a to be validated approach label May 3, 2022
@mui-bot
Copy link

mui-bot commented May 3, 2022

Details of bundle changes

@material-ui/core: parsed: +20.74% , gzip: +11.72%
@mui/material-next: parsed: +131.43% , gzip: +115.48%

Generated by 🚫 dangerJS against a4a3c0d

@mnajdova
Copy link
Member Author

mnajdova commented May 3, 2022

We probably will need to increase a bit more the resource_class. Looks like what was done in https://github.com/mui/material-ui/pull/31332/files may not be enough. Currently the test_types is failing because of insufficient memory.

@mnajdova mnajdova requested a review from michaldudak May 3, 2022 06:43
@@ -3,13 +3,7 @@
"children": { "type": { "name": "node" } },
"classes": { "type": { "name": "object" } },
"expandIcon": { "type": { "name": "node" } },
"focusVisibleClassName": { "type": { "name": "string" } },
"sx": {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sx prop here is basically duplicated type, as it is already defined in the ButtonBase. We can rely on the link towards the ButtonBase for documentation on the sx prop.

@michaldudak
Copy link
Member

Good job so far!
I've looked into the right-hand side of the chart - what was interesting for me is the checkExpression block that takes almost a second in your example. I played with the code a bit and found out that this is performed on the first component which is an OverridableComponent. When no such component is used in the code, the type-checking phase goes much faster.
It's a pity the trace does not allow us to go deeper and figure out where exactly the time is spent. There was some investigation in this matter done already (#19113 (comment)). I'll try to continue digging in this direction.

@mnajdova
Copy link
Member Author

I will close this one and open different PRs for the three things we want to try to optimize - OverridableComponent, sx prop and styled().

@mnajdova mnajdova closed this May 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proof of concept Studying and/or experimenting with a to be validated approach
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants