stitches icon indicating copy to clipboard operation
stitches copied to clipboard

Compiling Stitches without "strict": true, causes massive performance issues

Open andrewgeorgemitchell opened this issue 2 years ago • 15 comments

Bug report

Describe the bug

When compiling Stitches in a TS environment without "strict": true in tsconfig.json the compile time will jump from a few seconds to multiple minutes (~200 seconds).

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

1 Clone Repo

2 Install deps

  • yarn install

3 Run TS compiler (will take ~160-200 seconds)

  • yarn tsc

4 Enable strict mode in tsconfig.json line 10

  • "strict": true,

5 Run TS compiler (will take ~4 seconds)

  • yarn tsc

Expected behavior

TS build should not take ~200 seconds

Screenshots

Screen shot of slow compile (169.41s): ('strict': false)

image

Screen shot of normal compile (4.00s): ('strict': true)

image

System information

  • OS: [macOS]
  • Browser (if applies) [N/A]
  • Version of Stitches: [1.2.8]
  • Version of Node.js: [16.x]
  • Version of Typescript: [4.6.x, 4.7.x] (tested both)

Additional context

Possible Cause & Interesting observation

The issue when not in strict mode seems to be that Typescript spends a large amount of time comparing CSS objects to each other, you can see this behaviour for yourself by:

  • commenting out line 71 in src/components/Text/Text.tsx
  • uncommenting line 72 in src/components/Text/Text.tsx

andrewgeorgemitchell avatar Jun 09 '22 01:06 andrewgeorgemitchell

Typescript is the gift that keeps on giving 😄 I remember fixing a similar issue about a year ago. Thanks for reporting it.

hadihallak avatar Jun 09 '22 01:06 hadihallak

@andrewgeorgemitchell btw, really appreciate this detailed issue. super helpful 🙏

hadihallak avatar Jun 09 '22 01:06 hadihallak

@hadihallak Glad I could help/finally figured this one out 👍 We are loving Stitches as we use it to build out our design-system @ Drift so just let me know if there is anything I can do to help.

One more thing that just popped into my head that may or may not be relevant is that in the reproduction repo I only have 1 component which uses the line:

css={css}

While in the design-system this reproduction repo is based on we have a lot more components and yet when looking at the tsc --generateTrace trace its pretty obvious that it only slows down the first time it runs into

css={css}

and when it runs subsequent times it finishes them in seconds, so yeah just further evidence I guess that something strange is happening with typescript and comparing those types.

andrewgeorgemitchell avatar Jun 09 '22 01:06 andrewgeorgemitchell

Oh my goodness, THANK YOU @andrewgeorgemitchell for this quick fix! 🙏

If it helps at all @hadihallak, my Stitches project was fine with TS 4.5, got very slow in 4.6, was working great again in 4.7.2 and slow again in 4.7.3 (before changing strict to true). Could just be my individual experience but maybe a clue lies somewhere in the latest changelog...? (To be fair this back-and-forth flakiness could also mean the problem is more on TypeScript's side than here!)

https://github.com/microsoft/TypeScript/issues?q=milestone%3A%22TypeScript+4.7.3%22+

https://github.com/microsoft/TypeScript/compare/v4.7.2...v4.7.3

jakejarvis avatar Jun 13 '22 12:06 jakejarvis

@jakejarvis Yeah ever since typescript 4.6 we started having weird typescript behaviors in the types in Stitches.

hadihallak avatar Jun 13 '22 12:06 hadihallak

For anyone who's reading this and is experiencing degraded types performance, Please comment the time it takes to build your project with and without setting "strict": true in tsconfig.json Also please include both the TS and Node versions

hadihallak avatar Jun 13 '22 13:06 hadihallak

Node v16.15.1 TypeScript v4.7.3

{ "strict": true }: (1.63s)

$ tsc --noEmit --diagnostics
Files:              930
Lines:           174142
Nodes:           530418
Identifiers:     157583
Symbols:         113758
Types:               84
Instantiations:       0
Memory used:    184270K
I/O read:         0.14s
I/O write:        0.00s
Parse time:       1.24s
Bind time:        0.39s
Check time:       0.00s
Emit time:        0.00s
Total time:       1.63s

{ "strict": false }: (153.53s)

$ tsc --noEmit --diagnostics
Files:              930
Lines:           174142
Nodes:           530418
Identifiers:     157583
Symbols:         550041
Types:           408833
Instantiations: 2300116
Memory used:    989374K
I/O read:         0.06s
I/O write:        0.00s
Parse time:       1.48s
Bind time:        0.41s
Check time:     151.64s
Emit time:        0.00s
Total time:     153.53s

FWIW, the project is here: https://github.com/jakejarvis/jarv.is

jakejarvis avatar Jun 13 '22 13:06 jakejarvis

Yup, we are on TS 4.5.5 https://github.com/washingtonpost/wpds-ui-kit/blob/main/package.json#L178. We also have strict on https://github.com/washingtonpost/wpds-ui-kit/blob/main/tsconfig.base.json#L34.

We even have a note about the TS issue with 4.6.0 in our contributing docs https://github.com/washingtonpost/wpds-ui-kit/blob/main/docs/CONTRIBUTING.md#why-is-typescript-throwing-warnings-about-the-css-object-in-stitches

artmsilva avatar Jun 19 '22 03:06 artmsilva

We also ran into this issue in the last 2 weeks (after upgrading TS).

Node v16.17.0 TypeScript v4.8.3

Numbers shown below are from a high spec M1 mac. Numbers in CI are significantly slower (~4 minutes).

Baseline (strict: false):

Files:              3062
Lines:            411651
Nodes:           1437257
Identifiers:      472235
Symbols:         1428472
Types:            651800
Instantiations:  8278010
Memory used:    1667787K
I/O read:          0.36s
I/O write:         0.00s
Parse time:        2.04s
Bind time:         0.61s
Check time:      102.69s
Emit time:         0.00s
Total time:      105.33s

With strict: true:

Files:              3062
Lines:            411651
Nodes:           1437257
Identifiers:      472235
Symbols:         1297707
Types:            411234
Instantiations:  7545554
Memory used:    1060433K
I/O read:          0.34s
I/O write:         0.00s
Parse time:        1.98s
Bind time:         0.56s
Check time:       13.94s
Emit time:         0.00s
Total time:       16.48s

When making this change:

- export type CSS = Stitches.CSS<typeof stitches.config>;
+ export type CSS = any;
Files:              3062
Lines:            411652
Nodes:           1437252
Identifiers:      472232
Symbols:         1237087
Types:            391868
Instantiations:  5570696
Memory used:    1037047K
I/O read:          0.44s
I/O write:         0.00s
Parse time:        2.20s
Bind time:         0.60s
Check time:       12.13s
Emit time:         0.00s
Total time:       14.92s

smhutch avatar Sep 29 '22 09:09 smhutch

I'm getting this issue even with strict: true. So just by importing the Stitches.CSS type and using it on a prop the compile time increased by a factor of more than 10.

mstykow avatar Nov 08 '22 11:11 mstykow

Ok, guys. I identified the issue I think (at least im my codebase). The problem for me was the following snippet:

export const Component = () => <Element />

// ...

const Element = styled(AnotherElement, {})

To fix the issue, I needed to use the other way around for "Inheritance of Styles":

export const Component = () => <Element as={AnotherElement} />

// ...

const Element = styled("final-element (e.g. div)", {})

iduuck avatar Nov 24 '22 11:11 iduuck

I'm getting this issue with strict set to either true or false. Large check times basically making it unusable because the IDE just can't compile typescript quick enough.

Files:              460
Lines:           142712
Nodes:           455413
Identifiers:     155426
Symbols:         369677
Types:           306429
Instantiations: 1651124
Memory used:    834976K
I/O read:         0.02s
I/O write:        0.03s
Parse time:       0.57s
Bind time:        0.21s
Check time:      93.08s
Emit time:        0.27s
Total time:      94.14s

theomjones avatar Mar 02 '23 08:03 theomjones

@theomjones Have you seen my previous comment? When using some sort of props inferring, this is what causing me to have a loop in my typescript files, and then it takes very long to load. I refactored my application to not use styled(AnyComponent, {} but rather styled('div', {}) and use the as prop for this. This is making it easier and speedier.

iduuck avatar Mar 04 '23 10:03 iduuck

I have the same issue I added zod and now vs code in unbearably slow, I added zod in another project with strict mode and that is working fine

shessafridi avatar Apr 16 '23 23:04 shessafridi

Similar to others here, I had major issues getting this to work, whether with or without strict mode. After doing a lot of performance tracing on type checking, it appears to come down to the CSS type in css-utils.d.ts. I made a couple modifications to stitches in order to support updating TypeScript, including patching for the issue in #1078.

The key change though for the performance problem, not requiring any change to my code, was to modify the unknown property type intersection in css-util.d.ts. This is the diff:

 		[K: string]: (
 			| number
 			| string
-			| CSS<Media, Theme, ThemeMap, Utils>
 			| {}
 			| undefined
+			| any
 		)

This completely resolved my performance problem, and I don't think it will have significant negative impact on the developer experience. (NOTE: I'm using patch-package to apply this patch in my repo as we aren't on yarn v2 yet)

jasonaden avatar Apr 20 '23 16:04 jasonaden