-
-
Notifications
You must be signed in to change notification settings - Fork 247
Change the watch mode of TS compiler to 'UseFsEventsWithFallbackDynamicPolling' #256
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
Conversation
NeKJ
commented
Apr 20, 2019
- add typescriptWatchMode option
- add pre-defined enum 'ForkTsCheckerWebpackPlugin.TypescriptWatchMode' that consists of TS 3.4.x supported values for watch mode
- set the environment variable 'TSC_WATCHFILE' according to the options before the creation and execution of the compiler program
- append used TS Incremental API and TS watch mode settings to the information output
- update README.md with help about this new option
…icPolling' - add typescriptWatchMode option - add pre-defined enum 'ForkTsCheckerWebpackPlugin.TypescriptWatchMode' that consists of TS 3.4.x supported values for watch mode - set the environment variable 'TSC_WATCHFILE' according to the options before the creation and execution of the compiler program - append used TS Incremental API and TS watch mode settings to the information output - update README.md with help about this new option
TS uses internally the NodeJS doc:
TS, for some unknown to me, reason, defaults to However, I decided to use 'UseFsEventsWithFallbackDynamicPolling' value as the default mode because it makes TS to use 'fs.watch' and if that doesn't work/is not supported by the OS, it will fallback to the |
First of all: thank you! Great detective work 😁 Now that you've explained what the issue is (and provided a solution) I'm a-wondering... The solution is essentially set an environment variable either to this:
Or to the value supplied. It's completely cool that we can do this. I'm wondering whether it's a good idea. The complete win for me would be TypeScript itself having a better default. So before we look to merge this I think I'd like to raise this with the TypeScript team. Let's see where that leads. In the meantime, would you be able to characterise how each of these performed?:
|
Of course I agree that this is an issue of TS and that's where the fix should be done, not in this plugin and you did the right thing to raise this with them (I would too but you, as the maintainer of this, have much more ...weight). But for the time being we have this at least as a practical workaround for the users of this plugin. I didn't make any real measurements the first time because I didn't want to spent anymore time on it, but you asked nicely :p so here they are: I measured all of them, using
As we can see, the worst option of them all is the default behaviour of TS and next to it is the PriorityPollingInterval where it is a tad bit lower. DynamicPriority is at 0.5% and all rest at 0.2%. Therefore the These all are measurements on my own computer which is a PC running linux 64bit. To do this right,we will need measurements from other systems too (OSX, Windows etc). |
Hm. As a temporary measure, updating the {
"scripts": {
"watch": "TSC_WATCHFILE=UseFsEventsWithFallbackDynamicPolling webpack"
}
} So I'm not sure this may need a code change right now. Maybe just updating the README for the time being, or pinning an issue with that information would be enough until it is fixed upstream? (Disclaimer: I'm not the maintainer of this project, just giving my thoughts here) |
I want to see what the TypeScript team say before we proceed. I hope you understand, but taking away something from an API is a lot harder than adding it in the first place. Given there's a workaround that's usable by all right now, I don't think the urgency on this is high. I do massively appreciate the detective work done here it's super useful and helpful. I hope you understand my caution. Much ❤️ |
No worries, I don't care if it gets merged or not, I'm just glad that I could help to track down the issue. :) |
@johnnyreilly |
@InvictusMB that is really weird. Could you provide a reproduction repo? That would be of great help! |
@phryneas Not sure how to set that up. I've tried creating a fresh project with CRA3 and In my real codebase there are 500+ components and about 40 Another workaround I had was replacing all the top level Also I found that while TS process constantly generates high CPU load it does not cause any IO load. |
@InvictusMB have you tried the environment variable workaround? #256 (comment) Oh you have and it works; great! Yeah, I'm hoping behaviour is going to be changed in TypeScript itself - check out microsoft/TypeScript#31048 |
@johnnyreilly It is as if every |
Yup, I understand that concern. One thing I'd like you to report back on: does this only happen with Oh, and all things aside: afaik, Material UI discourages importing directly from |
Oh yeah, forgot to mention you @InvictusMB - the response above was for you :) |
@phryneas
Yes, I know that and I don't like it. Compiler/bundler inefficiencies should not define the way I write code. I actually hacked together a babel macro that expands namespace import into deep imports. |
It doesn't, |
@phryneas So, this is slow:
Flipping any of those options seems to make overall start up performance ok. The issue seems to be dependent on total RAM load or something else too. This time I was not able to reproduce it with When I was able to reproduce it, Using a macro shaves off 20-30% of build time consistently. Using TS 3.5 RC also makes performance acceptable. With 3.5 RC idle CPU load is ~25% and it drops to ~7% with I have no idea what to make of all this data. |
Yeah, looks like fork-ts-checker-webpack-plugin was a few versions ahead of TS when naming things 🤣 So, my current analysis on this is (please verify @johnnyreilly @piotr-oles - maybe you have some ideas on this?):
So I guess our culprit is somewhere in CompilerHost.processChanges. I guess what happens is this: a first typecheck (A) is started and before it is complete, you change something in the code. A new typecheck (B) is queued after (A). Inbetween, you make another change. (C) is queued after (B). By now, (A) is finished - but it is not the current typecheck, so results aren't shown to you. The more you edit, the more typechecks are queued up and they are done one-after-the-next. So your queue reaches a length where it might take hours until you get the final result. (that will be shown to you) @InvictusMB This is just a wild theory - but am I assuming right that this behaviour takes very long if you are editing in-between and is slow, but not extremely slow if you aren't touching your keyboard? @johnnyreilly @piotr-oles I just did a quick scan of the code so I might have missed a safeguard against such behaviour - could you please take a look and verify or debunk my theory? |
Reading the code again, it might be more of this scenario: (A) running ...which might also be problematic. But I think this is wild speculation at this point, I'm not really in a state of mind to dig too far into source code today. Will look back into this in a few days :) |
Having read and reread I think your analysis is solid. I'm pretty sure that describes the behaviour I'd expect. I wonder if @0xorial has anything to add to the understanding of the Very grateful we are too 🤗 Side note: in retrospect we probably should have called the option I wonder if we should move this discussion to a separate issue? The topics being discussed now no longer seems to be directly related to the file watching behaviour... |
@johnnyreilly I would not dare to make assumptions without some debugging - complexity of CompilerHost.ts and Typescript compiler are way higher than I would like to see :( Normally, it should process everything sequentially, and yes, multiple fast requests could create a longer queue of processing... @InvictusMB, for my curiosity, what is your current timing for initial/incremental build with best config that you could get? |
No, there is no editing happening concurrently with the ongoing type checking when I benchmark things. @0xorial
and using a macro for MUI imports and TS 3.3.1 I get: On Mac the initial builds are roughly 2x faster, incrementals are usually under 1 sec and none of the settings had any statistically significant impact. While @phryneas' theory might not explain the initial start time, it certainly hints to why I now get stale type checker data on incremental builds from time to time. I don't know if this is due to the watcher mode or async mode, or a combination of those. This hasn't happened before. Before moving to CRA 3 with |
…e testing) We're trying to solve hanging builds, see discussions here: * facebook#7003 (comment) * TypeStrong/fork-ts-checker-webpack-plugin#256
I'm closing it as I was able to release v5.0.0-alpha.1 version which uses webpack watch system instead so this issue is no longer a case :) |