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

[@types/styled-components] Performance issues on compiler #34391

Closed
4 tasks done
voliva opened this issue Apr 2, 2019 · 56 comments
Closed
4 tasks done

[@types/styled-components] Performance issues on compiler #34391

voliva opened this issue Apr 2, 2019 · 56 comments

Comments

@voliva
Copy link

voliva commented Apr 2, 2019

Adding the latest version of @types/styled-components to an existing project causes build times to go up by about 1-2 minutes, by using the latest [email protected].

By using this seed repo, I've tested the following versions:

w/o     2.3s
4.0.0   5.6s
4.1.0   8.0s
4.1.5   8.0s
4.1.10  10.1s
4.1.11  90.1s
4.1.12  97.1s

My machine is a Linux 4.18.0 (Ubuntu 18.10) laptop, with a i7-6700HQ CPU @ 2.60GHz

It seems clear that the release 4.1.11 is what's causing this performance issue. The PR for this release is #33061. As of why, I really don't know - I tried to dig into the internals of the compiler to see where it was getting stuck at, but I couldn't understand it.

@eps1lon
Copy link
Collaborator

eps1lon commented Apr 3, 2019

Does this also happen with typescript 3.3?

@DylanJu
Copy link

DylanJu commented Apr 3, 2019

I experienced same issue

package.json

devDependency

"@babel/core": "^7.4.0",
"@babel/plugin-proposal-class-properties": "^7.4.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-async-to-generator": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3",
"babel-jest": "^24.5.0",
"babel-loader": "^8.0.5",
"babel-plugin-styled-components": "^1.10.0",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"jest": "^24.5.0",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"react-svg-loader": "^2.1.0",
"regenerator-runtime": "^0.13.2",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"ts-loader": "^5.3.3",
"typescript-tslint-plugin": "^0.3.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1"

dependency

"@babel/polyfill": "^7.4.0",
"@loadable/component": "^5.7.0",
"@types/loadable__component": "^5.6.0",
"@types/react": "^16.8.10",
"@types/react-dom": "^16.8.3",
"@types/react-router-dom": "^4.3.1",
"@types/styled-components": "4.1.5",
"axios": "^0.18.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router": "^5.0.0",
"react-router-dom": "^5.0.0",
"styled-components": "^4.2.0",
"styled-normalize": "^8.0.6",
"typescript": "^3.4.1"

My problem is that it looks like webpack & webpack-dev-server can not parse @types/styled-components. Because when use just styled-components, there was no problem. It always happen when use @types/[email protected] same time.

Before seeing issue of @voliva, I found infinite loop problem of webpack because it use cpu resource 100%.

After changing @types/styled-compoents version to 4.1.5, it looks like everything is ok.

@michsa
Copy link

michsa commented Apr 3, 2019

@eps1lon: Nope, typescript 3.3 is fine; specifically, it looks like the issue starts under release 3.4.0-dev.20190226.

Using @voliva's seed repo, I believe I've pinpointed the issue to the recursive usage of OmitU, added in @types/styled-components release 4.1.1. Here is its definition:

type OmitU<T, K extends keyof T> = T extends any ? PickU<T, Exclude<keyof T, K>> : never;

And here are both of the places OmitU is used in index.d.ts:

Definition of WithOptionalTheme

type WithOptionalTheme<P extends { theme?: T }, T> = OmitU<P, "theme"> & {
    theme?: T;
};

Usage of WithOptionalTheme (in the definition of StyledComponentProps)

WithOptionalTheme<
    OmitU<
        ReactDefaultizedProps<
            C,
            React.ComponentPropsWithRef<C>
        > & O,
        A
    > & Partial<PickU<React.ComponentPropsWithRef<C> & O, A>>,
    T
>

Something about the union-distributed OmitU mapping over another OmitU seems to be tripping up the compiler. If either or both of these instances is replaced with a regular Omit that does not distribute over unions, the compile time is reduced to a reasonable 10 seconds or so under typescript 3.4.1.

(Note that the ReactDefaultizedProps type also references PickU, which may help to explain the especially long running times in the second row of the table below.)

To test this, I swapped out one or both of the distributed OmitUs with one of the following:

type OmitPickU<T, K extends keyof T> = PickU<T, Exclude<keyof T, K>>;
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

Here is time yarn tsc run against typescript 3.4.1, 3.4.0-dev.20190226, and the immediate prior release, 3.4.0-dev.20190223:

WithOptionalTheme definition WithOptionalTheme usage typescript 3.4.1 typescript 3.4.0-dev.20190226 typescript 3.4.0-dev.20190223
OmitU OmitU 1m28.984s 0m55.853s 0m6.031s
OmitU OmitPickU 2m49.492s 1m49.457s 0m5.961s
OmitPickU OmitU 1m10.313s 0m35.278s 0m6.125s
OmitPickU OmitPickU 0m10.501s 0m6.947s 0m6.055s
OmitU Omit 0m9.611s 0m6.781s 0m6.102s
Omit OmitU 0m10.471s 0m7.451s ...etc
OmitPickU Omit 0m9.654s 0m6.796s
Omit OmitPickU 0m8.990s 0m6.485s
Omit Omit 0m9.730s 0m6.815s

Running times for typescript 3.3.3 and 3.3.4000 are consistent with 3.4.0-dev.20190223 -- roughly 6 seconds across the board.

I'm not familiar enough with styled-components to propose a solution, but I hope this data helps!

@flut1
Copy link

flut1 commented Apr 3, 2019

I can confirm I have the same issue. Downgrading @types/styled-components to 4.1.5 worked for me as well. I'm on typescript 3.4.1

@eps1lon
Copy link
Collaborator

eps1lon commented Apr 3, 2019

@michsa I was expecting some reduction but not a 10x. Since this was introduced in typescript 3.4 could you open an issue in the typescript repo as well? I would like to make sure we don't revert a bug fix if it's a regression that should be fixed in typescript.

@voliva
Copy link
Author

voliva commented Apr 3, 2019

Sorry I initially didn't search in typescript's github, I found this issue they are currently investigating: microsoft/TypeScript#30663

@mjbvz
Copy link
Collaborator

mjbvz commented Apr 5, 2019

@weswigham @RyanCavanaugh Can we please look into quickly publishing a revert to the styled components types that does not have the perf issues on 3.4.

With the VS Code 1.33 release, a lot of js users are going to be downloading the bugged types through automatic type acquisition. Once this happens, to get out of the bad state, I believe that you either have to clear your automatic type acquisition cache or install the fixed @types/styled-components. Neither are good experiences for js users. The longer the poorly performing typings are the latest published version the more users who are going to be effected (which is a bad experience for them and lots of extra work for us too)

@evelant
Copy link

evelant commented Sep 11, 2019

This seems like it may still be an issue with @types/styled-components 4.1.19 and TS 3.6.3. TS completion and error highlighting taking 5-10+ seconds on 2018 i7 macbook pro 15. Need to do some more investigation.

@weswigham
Copy link
Contributor

Erm, the OP is talking about 90s compilations (a 9x jump in time form the prior styled components version), seeing as both later version of TS have mitigations in place and later version of styled components were simplified to not have so much of a perf issues, 5-10s is maybe just your project and deps behaving normally.

@evelant
Copy link

evelant commented Sep 11, 2019

I hope not! It's frustratingly slow now when it wasn't in the past. I'm going to look into it further and report back here if it appears to be related to this issue.

@aqzhyi
Copy link

aqzhyi commented Aug 24, 2020

I'm experiencing the hell in the CSS-in-JS haven when I am coding with VSCode.

@ghost
Copy link

ghost commented Aug 24, 2020

@AndrewMorsillo @hilezir I switched from styled-components to styletron, using TS 4. Performance in styletron is much better both in vscode and in the browser. But I don't know about styletron on React Native.

@Andrew1431
Copy link

@AndrewMorsillo @hilezir I switched from styled-components to styletron, using TS 4. Performance in styletron is much better both in vscode and in the browser. But I don't know about styletron on React Native.

Is too late for us to make this change but I haven't heard of styletron and definitely like the looks of it more than styled components.

@JulianLang
Copy link

Will there be a new issue or will this issue be reopened? There are still great performance issues with @types/styled-components 5.1.2 and TS 3.9.7

@nfarina
Copy link

nfarina commented Oct 5, 2020

Spent a whole day trying to figure out how to speed up VSCode and finally figured out it was @types/styled-components. When that's installed, just typing anything in the editor would cause tsserver.js (as shown via VSCode Process Explorer) to spike >100% CPU and grow unbounded in memory. Simply removing @types/styled-components fixed this.

I was using TypeScript 4.0.3 and @types/styled-components 5.1.3.

@prabhuignoto
Copy link

can someone suggest a better alternative to styled-components. my vscode completely freezes.

@aqzhyi
Copy link

aqzhyi commented Oct 7, 2020

can someone suggest a better alternative to styled-components. my vscode completely freezes.

try this?

  1. https://material-ui.com/styles/basics/#material-ui-styles

  2. https://emotion.sh/docs/styled#styling-elements-and-components

@bdelaforest
Copy link

bdelaforest commented Oct 7, 2020

There is actually a Pull Request open to improve styled-components' types performance: #46510.

@pierpo
Copy link

pierpo commented Jul 7, 2021

I am still experiencing very slow type checks with tsserver 😢

I compared on the following component :

<Title variant="header">Hello</Title>

If I remove the e from "header", it becomes "hader" with is a type error. But my editor takes 10 seconds to show it to me! If I try to autocomplete, it takes like ~5 seconds.

I tried to switch to emotion and did the same experiment... It takes less than 1 second for both type check and autocompletion to work!

I asked some colleagues and they had the same issue on other projects.
Any idea?

@allohamora
Copy link

Yesterday i had vscode tsserver performance issue in next.js typescript styled-components project. I fix it by removing styled-normalize from project and import it directly by link tag in _app.tsx.

@pierpo
Copy link

pierpo commented Jul 15, 2021

Unfortunately I do not use styled-normalize 😞 so it can't be the issue!

@naor555666
Copy link

I had the same issue, switched to emotion and it works actually much better

@Adryel123
Copy link

My intelisense is extremally slow when using the 5.1.9 version. Errors were taking over 10 seconds to show up and the intelisense was taking over 5 seconds.

The issue disappeared when downgrading to 4.0.3 version. Not the best solution but worked for me.

@pierpo
Copy link

pierpo commented Sep 21, 2021

We should identify what's changed, then!

Also, we could take inspiration from emotion's types. They work really well, and the API is the same.

@googidaddy
Copy link

My intelisense is extremally slow when using the 5.1.9 version. Errors were taking over 10 seconds to show up and the intelisense was taking over 5 seconds.

The issue disappeared when downgrading to 4.0.3 version. Not the best solution but worked for me.

same 2!!!

@Andrew1431
Copy link

Why is this issue closed? Everyone seems to be having this issue.

@Andrew1431
Copy link

I am still experiencing very slow type checks with tsserver 😢

I compared on the following component :

<Title variant="header">Hello</Title>

If I remove the e from "header", it becomes "hader" with is a type error. But my editor takes 10 seconds to show it to me! If I try to autocomplete, it takes like ~5 seconds.

I tried to switch to emotion and did the same experiment... It takes less than 1 second for both type check and autocompletion to work!

I asked some colleagues and they had the same issue on other projects. Any idea?

Do you find emotion has a similar / replaceable API with styled-components? I am working on getting our compilation speeds back up to snuff only to realize I think this is the only issue.

@pierpo
Copy link

pierpo commented Oct 26, 2021

Well, the migration is quite easy. It depends on the size of your project, but it's mostly replacing imports from styled-components to emotion.
You'll have some stuff changing, some slight differences in the API, but it should be mostly working. I'd suggest to give it a try!

On react-native, there is an annoying problem with emotion though (but it has a solution).

This doesn't work anymore :

const MY_INT = 40;
styled.View`
  margin: ${MY_INT}px;
`

because emotion doesn't convert numbers to string properly inside template strings.
You need to replace it with this :

const MY_INT = 40;
styled.View`
  margin: ${MY_INT + 'px'};
`

Which does exactly the same but won't cause any issue to emotion.
The annoying thing with this problem is that it's silent, so you need to carefully check. If you use styled components this way, I'd suggest to search for }px in your project.

@nfarina
Copy link

nfarina commented Oct 26, 2021

In case it helps anyone, I solved my own problem by creating my own type definitions for Styled Components. It was intended to be a temporary fix but ended up doing everything I needed. If you'd like to use it, just remove your dependency on @types/styled-components and drop in this file (and reference it in your tsconfig): https://gist.github.com/nfarina/ea282fbb01574e95d87ce661f7fe8630

@googidaddy
Copy link

TSSERVER broken in 5.1.15!!!!!!!!!!!!!!!!!

@Foxhoundn
Copy link

A little bump here - removing @types/styled-components 5.1.15 fixed a lot of perfomance issues in my VSCode.

@emiomacollins
Copy link

Hi Everyone I've been having this issue for a while now. Downgrading @types/styled-components worked for me.

yarn add @types/[email protected]

@lin2006yuo
Copy link

@types/styled-components 5.1.25 still slow🙁

@djskinner
Copy link

I have discovered that, for us at least, a lot of the performance issues stem from the types deriving massive unions of all the valid JSX elements. Such large unions can be a performance issue as described here: https://github.com/microsoft/TypeScript/wiki/Performance#preferring-base-types-over-unions

So I created custom types that replace usages of JSX.IntrinsicElements with JSXIntrinsicElementsMinimal:

type JSXIntrinsicElementsMinimal = Pick<
  JSX.IntrinsicElements,
  | 'div'
  | 'span'
  | 'img'
  | 'p'
  | 'h1'
  | 'h2'
  | 'h3'
  | 'h4'
  | 'header'
  | 'footer'
  | 'section'
  | 'input'
  | 'time'
  | 'button'
  | 'label'
  | 'nav'
  | 'svg'
  | 'hr'
  | 'ul'
  | 'ol'
  | 'li'
>;

I just define the element types I actually use and add them as necessary. I'm never going to do styled.audio, for example, so there's no need to have it in there contributing to the slowness.

It makes a noticeable and worthwhile difference and I haven't needed to sacrifice any typing capabilities.

@yleflour
Copy link

@djskinner Do you have the steps to achieve the replacements?
Did you have to clone the entire styled-components typings in your source code or did you find a way to override its usage in @types/styled-components?

@djskinner
Copy link

I created a file called styled-components-fast.ts and changed all imports to use this file instead:

- import styled from 'styled-components'
+ import styled from 'styled-components-fast'

Note: the way the project is set up with webpack module resolution allows for this type of absolute import. You may need to do something like import styled from './styled-components-fast' depending on your setup.

styled-components-fast.ts mostly just re-exports types and implementations from styled-components but anywhere any type refers to JSX.IntrinsicElements either explicitly or implicitly then the type is copied into this file and changed to refer to JSXIntrinsicElementsMinimal, instead of direct re-exporting. It looks like this currently: https://gist.github.com/djskinner/515d96af8d8b59bd6304bcddd7a26bc6

Note:

  • I have only re-exported the things currently being used so you may need to re-export more stuff as necessary
  • I think I removed some deprecated APIs from some of the modified types
  • You should update the JSXIntrinsicElementsMinimal union to only include the elements you use with styled for the best performance

@vavra7
Copy link

vavra7 commented Oct 28, 2022

Please open this. Still a big problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests