react-spring causes tsserver / typescript to lag multiple seconds

Created on 1 Apr 2019  ·  41Comments  ·  Source: pmndrs/react-spring

If you can hear my keystrokes you can see a huge delay suddenly happens when I import react-spring. I believe the types must be causing some trouble somewhere for typescript. I'm using typescript 3.4.1 and react-spring 8.0.18.

https://v.usetapes.com/hNl9HhHlSE

typescript

Most helpful comment

Yep, me too. To be fair react-spring seems to be using some pretty sophisticated types to declare all the relationships between different arguments/object properties. The flexibility if the react-spring API also sure doesn't help. @aleclarson do you think it is possible that this problem has no other solution for now than to make a tradeoff between mathematically sound types and performance? I mean perfectly sound types are not really of any use if they break the editor and people end up doing declare module "react-spring" anyway.

All 41 comments

This combined with https://github.com/react-spring/react-spring/issues/571 lost me quite a bit of debugging time tonight. Don't take this wrong, if the speed issue replicates it may be worth removing the types altogether until they are fixed, wrong types being worse than none.

I can confirm that using react-spring with typescript makes VsCode noticably slower and less responsive.

I ... wouldn't know how to fix this tbh. I trust that contributors will figure that out on their own, all PR's are welcome of course. But i think we're making good progress with native TS types. @jacobrask has already transformed large parts of the code and perhaps at some point we can dump the definition files. But generally - if you need more TS support for this lib, please reach out - i will gladly deal out maintenance rights, i think it makes sense that a group of people watches over it.

Yea I just wanted to note. It’s something weird happening as we use a ton
of TS and this is the first time I’ve seen it. It’s also a 3-4 second
delay, which is intense (accompanied with 100% cpu on both vscode and the
compiler). So wanted to note for anyone else pulling hair.

I got it fixed by just adding an override declare module “react-spring”
for now.

@natew What are the callsites (if any) for animated or useSpring in your example?

It's the first time I've ever seen <<unresolved>> as typescript value and I've tried many weird typings :) I'm thinking it's worth investigating as some TS edge-case/regression^^

Ok, now more seriously - I will not propose to make PR (since I'm quite new to this project), but here's patch-package patch.

It's really quick work but seems fine to me. I've dumbed down those problematic inferences and added few missing props and overloads to useTransition.

https://gist.github.com/vadistic/4878ac666a7bebde743eccd5ae01fad6

I think the typings may just be a bit too clever - they're trying to use types to validate corresponding properties between different arguments, and it's just doing too much at once.

I'm in the process of improving the types. I'll have a PR up soon.

@aleclarson Sweet. It might be good idea to try and write the various examples from the react spring site in typescript and make sure they pass tsc, similar to the *test.ts files in definitely typed definitions

The react-spring typings were the reason I logged https://github.com/Microsoft/TypeScript/issues/29949. Glad to see them getting addressed in this repo too! The old typings weren’t _wrong_ — they just made it easy to hit this Typescript bug ;)

The new types are available in the v9 branch. I hope to get v9.0.0-beta released soon.

You can use v9 like this now: yarn add react-spring@next

Let us know how it goes: #642

I still have issues with this on the newest beta. Importing animated slows vs code down considerably.

_Originally posted by @ksaldana1 in https://github.com/react-spring/react-spring/issues/642#issuecomment-496356875_

I had been having some issues with VSCode performance recently and I spent some time looking into it tonight—for the particular project I'm working on it seems that the new TS typings are the cause for a good bulk of my Intellisense / tsserver slowdown. Here are some rough numbers from the VSCode process monitor. This is running the latest 3.5-rc build of TypeScript.

File at rest (with v9 typings active):
Screen Shot 2019-05-27 at 9 54 46 PM

1 second after save/change (CPU spikes up to 280%):
Screen Shot 2019-05-27 at 9 56 29 PM

File at rest (typings commented out):
Screen Shot 2019-05-27 at 9 57 43 PM

It's hard for me to even get a picture of the jump without the typings, as it garbage collects pretty quick (spikes to ~400 MB/85%-100% CPU usage). Looking at the typings themselves, there's some pretty crazy stuff going on (hard API to type), so I'm not entirely surprised to find this. Something we probably want to keep an eye on though, as it's been a real drag on my TS dev experience lately... enough that I've disabled these typings for now.

This isn't an entirely unique problem as styled-components has recently had some issues.

To anyone facing this: Run @react-spring/envinfo and create a gist with the output like this.
Then paste that link here. Thanks!

I can't reproduce this on my machine. ™️

Can someone please dig into their node_modules and comment out random imports until the lag stops? You can start in node_modules/@react-spring/web/index.d.ts and follow the imports until you find the offending type(s).

Here's a gist from running @react-spring/envinfo: https://gist.github.com/dagstuan/51b39f6968ef0f6b47c59a3f4d53f736

As I've said in the past, animated seems to be the main culprit of the slowdowns. I'm not a typescript expert, but animated looks to be using quite a bit of recursion in the type, so there might be something there? I have created a small video to show how VS Code behaves when I declare AnimatedProps to be any instead of the current declaration, which shows VS Code type checking originally running very slowly, and then speeding up when I define AnimatedProps as any: https://www.youtube.com/watch?v=vs88fxuuJIo

I can recreate this issue both in MacOS and in Windows 10.

The code from the video is here: https://github.com/dagstuan/react-spring-test

I'm on a Mac mini (3.2 GHz Intel Core i7), and the difference is barely noticeable. (Which doesn't make debugging easy. 😑)

You've tried running VSCode without extensions, right?
(from the command line: code --disable-extensions)

My guess is that mapping over React.CSSProperties should be minimized as much as possible, since it's a huge type. TypeScript seems to trip on massive mapped types, currently.

Yeah extensions are not related to the slowdown :)

@dagstuan Thanks for your help! Can you try this commit? https://github.com/react-spring/react-spring/commit/cf90971008bcb21ba8559912226aca71cbfb714c

The idea is "maybe caching keyof React.CSSProperties is good enough"

Otherwise, I guess keyof T & CSSPropertyNames is the bottleneck. 🤔 Though, I'm not experienced with fixing TypeScript perf issues, so it's hard to say.

@aleclarson I tried cf90971 but unfortunately I can't really see a difference in performance :(

I think you are right with keyof T & CSSPropertyNames being a bottleneck. If i declare CSSValidProperties like this: type CSSValidProperties<T extends object> = { [P in keyof T]: P }[keyof T];, the type checking speeds up considerably.

The next move is reporting that to the TypeScript folks. Does anyone volunteer to open an issue?

I already logged https://github.com/microsoft/TypeScript/issues/29949 a while ago, specifically due to the react-spring typings. Wes Wigham explained that the issue was due to the ref field causing an explosion of intersections in union types.

There may be another issue at play here, but the issue I logged is still technically marked "open".

Is there any short-term workaround for this? This is an incredible tool, but unfortunately, TSServer becomes virtually unusable for me in most projects that I try to implement react-spring in.

I pushed dc142d7 to the v9 branch. It makes the ref prop an any type to avoid the memory issue. Try it by cloning the v9 branch by following this guide. Once someone confirms that it works, I'll publish a new beta with it. Thanks!

I'll take a look tonight, thanks so much for looking into this!

@aleclarson It still seems to have the same issue once linking. I've confirmed it's correctly referencing the linked package, and once animated is imported, TSServer slows down considerably.

Echoing @cdebotton: after importing animated, VSCode becomes unbearably slow.

For others looking for a temporary fix, this worked for me:

// Remove this once this issue is resolved: https://github.com/react-spring/react-spring/issues/613
declare module 'react-spring' {
  export const animated: any;
}

Edit: I was a bit hasty: while this makes VSCode no longer unbearably slow, there is still a several second lag for type-related operations, so something else is causing the issue as well. I'm using the latest non-beta version (8.0.27) of the library.

Yup, this issue is happening for me as well. Took me quite a long while to figure out it was react-spring and I've been debugging through a typescript github issue until I finally singled it down to react-spring. My issue is literally as simple as npm installing react-spring. It takes 5+ seconds to get any autocomplete to load or error squiggles to disappear after fixing. Have a single core that will spike to 100%.

The moment I uninstall react-spring everything is all rainbows again. Autocommplete works flawlessly although. However, although one of my CPU cores isn't chugging at 100%, they are still chugging a bit and my laptop sounds like a wind turbine.

EDIT: None of the fixes listed work for me either including react-spring@next

I am running on Deepin OS - Linux

Not making any promises, but did you try with the latest canary and typescript@beta? I still can't seem to reproduce this on my machine.. 🤦‍♂

Not making any promises, but did you try with the latest canary and typescript@beta? I still can't seem to reproduce this on my machine..

I have not, let me give that a shot and I'll report back. :crossed_fingers:

@aleclarson Unfortunately, it did not fix the issue. BUT....for some reason it didn't seem like my autocomplete was "as" unresponsive with slow loading and sometimes would give a autocomplete options within a second rather than the 5+ seconds it normally does with React Spring. However, that was only on occasion, most of the time it still took 5+ seconds. Again, without react-spring my autocomplete is instantaneous.

I went ahead and took a screenshot of "htop" before the beta and after with the CPU spiking. I don't know if you can make better sense of it than me.
Using react-spring before upgrading to beta: DeepinScreenshot_dde-desktop_20191010094037
Using react-spring after updating to beta: DeepinScreenshot_dde-desktop_20191011095830

I went ahead and saved the verbose tsserver logging as well. You can see in there that the response for autocomplete (at least that's what I'm assuming it is) go from milliseconds to full seconds. It took about a minute or so until it started getting slow and spiking my CPU.

TSServer Log: tsserver.log.txt

Yep, me too. To be fair react-spring seems to be using some pretty sophisticated types to declare all the relationships between different arguments/object properties. The flexibility if the react-spring API also sure doesn't help. @aleclarson do you think it is possible that this problem has no other solution for now than to make a tradeoff between mathematically sound types and performance? I mean perfectly sound types are not really of any use if they break the editor and people end up doing declare module "react-spring" anyway.

Yeah, this is still pretty bad. I thought I was going crazy when I noticed tsserver was suddenly crippled after adding this library to my project. I'd much rather have less correct but functional types than _no_ types at all, which is my current situation since I have to override the exports with any.

Like I said before, I can't reproduce the issue on my Mac mini (2018), so if anyone wants to figure out which type(s) need to be simplified, I will take a PR. If you have any questions about setting up the project locally, open an issue with the problem(s) you're having.

Haven't investigated the actual typings very far yet, but I have noticed something interesting about the issue. It seems to worsen in severity the longer you work on a file that imports those typings. Initially, performance is fine, then you write a few lines (make a few requests to tsserver) and it starts to respond progressively slower and slower. @aleclarson, that could possibly be the reason you're unable to reproduce it. Anyway, I'll dig into the typings themselves more in a bit.

Having the same issue with v9.0.0-canary.808.17.55c5691.

Have not dug into it yet, but just adding it to my standard VS Code workspace results in instant slow down to IntelliSense.

I have just updated to 9.0.0-beta.34, restarted the TS server and the performance issues seem to be resolved. My issues were definitely related to the useSpring import, not animated.

Edit: After a while editing, the performance does seem to fall off a clip as has been reported above.

any update on when this will be fixed?

Can you please put some instructions on the docs installing section for Typescript?
It futzed around me for looking the answer to the TypeScript!

Thanks

Was this page helpful?
0 / 5 - 0 ratings