-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Slow TypeScript compile time #4323
Comments
I thought we had an issue, but I can't find it. This is tracked though as one of the key benchmarks of Deno. We have done several changes to improve it, including semi-recently warming the compiler with an old program and including it as part of the snapshot. That increased performance about 30%. Prior to that, we made dependency resolution async, and we did it all upfront before we did the AST parse in the compiler. It is worth noting that the performance problem isn't linear. The biggest cost is spinning up the compiler all together. Compiling 2 files is only a small amount over compiling 1 file. There are still a few areas of investigation, like looking if buildinfo would increase performance at all. Also, @bartlomieju and I did talk about potentially keeping the compiler running, but that wouldn't help startup. The next biggest bump, but again, that wouldn't be substantial, is to do the dependency analysis in Rust via swc. Bigger projects it will certainly speed up, but it won't speed up that initial startup time. It has been a while since looking at it in depth, but it will be lots of small wins over a period of time. On what basis are you suggesting the <=200ms? What sort of machine/system? What sort of "single file"? |
It is good to hear this is being worked on. According to the graphs, cold relative import is sitting at around 500ms. That's not representative of the slow compile times I am seeing. I'm currently developing on a 16 cpu 8 GB VM. VSCode eats about 70% of the RAM and the processor is nearly always idle so I don't believe it is for lack of compute power. By single file I mean I am only making changes to a single file (<=200 LOC) before recompiling. 200ms would mean the experience would be closer to a Go build. With the 30% improvement number, does that mean it is still doing work on already compiled files? I would love to have the option to skip type checking and just have the modified file stripped of types especially during development where a warmed-up IDE is providing type checking. Keeping deno warm would be interesting as booting deno is is probably taking up some wall time as well. |
Whenever you change one file, TypeScript fetches and loads all the dependencies, so it can type check it. The AST is not serializable (see microsoft/TypeScript#33502), so it is difficult to "cache" the parsing of non changed files. There is buildinfo, but I don't know if it would really buy us anything more than the old program does.
That is certainly a possibility. That is something we would likely do in swc as well, and it would be blazing fast. Ry and I have talked about it in general terms, but this discussion here is a compelling use case. It certainly would be more preferable than a watch mode. |
Ultimately I hope we can use SWC instead of the official TS compiler - this will offer massive exe size and perf improvements. @kdy1 has a very interesting WIP branch here https://github.com/kdy1/swc/tree/ts-checker but it's obvious we won't be able to replace TSC with SWC any time soon. For the foreseeable future, there may be some yet undiscovered bugs in our interface to TSC that could help this, but it seems unlikely to me that we'll see any order-of-magnitude gains. TS has said they're working on performance in the next release - we'll see what that amounts to. One thing we could do is offer a switch to not do type checking on every run - or even asynchronously. This would speed things up greatly... but it seems like a hack to me. (I'm also surprised we don't have an issue for this already. As @kitsonk mention, we've been tracking compile speed since day one on the benchmarks page.) |
I do think though that a |
Agreed. A |
I'm probably bringing up an already discussed point, but what are the current thoughts on making type checking opt-in rather than the default? If it's not the default, then transpiling could always be done with swc. As has been said, during development people's editors can do the type checking and perhaps there could be an additional |
I'm open to having the default not type check. Maybe rather than having |
If required, I will extract typescript stripper from the transforms crate. It would be easy as it does not depend on other transforms. |
Hrmmmm... that makes me totally uncomfortable to be honest... One of the main use cases for me has always been the support for TypeScript which enforces the TypeScript syntax. Not type checking defeats the whole purpose of TypeScript to me. That is like saying "just run the JavaScript without syntax checking". Yes, there are other possible ways to enforce the types before running the workload in Deno, but those are optional. I would personally be very very very sad if we didn't type check by default. Type checking is a heck of a lot more than linting. |
I would find it weird for type checking to be a part of I'm open for it to not type check by default especially if a lock file is used. With compiled languages we can just distribute a binary and all user's don't need to run a checker. Given this:
Then type checking isn't really necessary there.
Looking at the number of downloads for As @dsherret mentions, that would enable using SWC for transpilation which would help speed up the developer loop. Still I would find it a bit odd if the default was off. I would suggest |
I wouldn't like |
In any case I think |
Besides speed, having P.S. Type-check speed can probably be improved a lot in the future with all crazy caching mechanisms especially at development time. |
Hi Guys 👋 I read this at https://deno.land/v1
I'm very curious about that. Here the good place to follow the discussion? |
@tony-go I think follow it here swc-project/swc#571 and in this thread. |
Thanks @dsherret |
By the way, on that idea of rewriting the type checker in Rust, I don't believe it would be worth it to do... the TS team has a lot of talented individuals working full time professionally on the problem. It will be a massive undertaking to catch up and use up a lot of time staying up to date. I think we could all use our time more effectively solving other problems. I think something like "solution 2" mentioned in #5431 would be a lot better because we could remove the type checker from the runtime. Regarding the concern of "defeating the whole purpose of TypeScript": in my opinion, the largest value Deno brings to me is that it can run my TS code without me needing to setup or do an intermediate step. I don't think it defeats the whole purpose of TypeScript at all because I can still run type checking on that code... I'm just doing that separately from the runtime. |
Just like to express my two cents worth. It may not be somewhat relevant to this issue but, well, I see so many people raising compiling and performance issues with TypeScript that I finally feel compelled to debunk the TypeScript bandwagon. TLDR; Even some parts of Deno are written in vanilla JS. Your solution is to not write all your code in TypeScript, but to exercise judgement and use as required. For JS codes, use type-checking library for runtime checking, and you won't need to complain about TypeScript's "lack of" for things it is not meant do. Sure, TypeScript is one certain way to enforce some discipline and strengthen typing. But so much code ends up using Where one is compelled to repeatedly use In the end, if you think writing in full Typescript is a silver bullet, you gave up the very good perks that Javascript offered, and exchanged them for an almost strong-typed language; that if you had wanted a strong-typed language, those perks would have to be given up for anyway. If so, you are better off using other languages. This is not even mentioning the lack of runtime type-checking, and how confused TS backers have believed TS to be the be-all and end-all, existentially disrupting APIs that need validation at runtime. See how clumsy Typescript becomes to do runtime checking. TypeScript and Javascript should possibly be best used in combination. And Javascript should just widely use a small type-checking library that will catch runtime violations (linting is a bonus). It can easily be very minimal, like just Further, even without strong-typing, quality of an application are nowadays assured by tests, an established basic requirement, that would work in tandem to compliment the type-checking within the code. This limits the use of TypeScript to just a small area of core features that are heavily depended upon. Divide your code up into dire areas (use TS) and others that will benefit from flexibility (us JS). Both areas can use a JS type-checking library. Albeit one can say its up to discipline to write tests or use the library, such is true for using So take away |
@calvintwr This issue isn't about discussing the validity of using TypeScript. It's about making compile time faster or skipping it (in favor of the faster in-IDE type checking). This is particularly important for deno because all users (including end-users and serverless containers) need to wait for that slow type-checking. This is why I agree with @ry that making no checking be the default is worth considering. Developers can easily enable type-checking in Deno or more likely, let their IDE or CI do that. That said, if I am able to or already have a compiling step (babel etc), I'm going to use TypeScript. For me, it is more of a question of using noImplicitAny or not. I prefer |
@brandonkal I see. Yup I missed out the point on IDE type checking, that makes sense. Thanks for highlighting. To further this quasi-conclusion on
|
That increases the complexity a lot with little real benefit. |
As mention by @brandonkal lot of people tend to do type checking in a separate process. So, giving the possibility to deactivate type check with |
I think using anything other than the official TypeScript compiler would be crazy. If you need speed for development, then just do the type stripping with |
Hmm, I thought that switching transpiler should be the easier task. SWC, esbuild etc. uses faster transpiler, because they just remove the types and calls it a day. Switching a type checker to some self-made thing is a crazy task which is not doable in my opinion. The type checker is TS teams task. I also love that all the discussions here comes back to the same square, should the type checking be on by default or not? I think for TS the type checking should be turned on, but it could be ran asynchronously in separate thread while transpiler does it's thing as fast as possible. We would get the fast restart and type-safety. |
@Ciantic but why to try to build a custom way to handle types. If you want to skip types and you use |
@apiel there is ideological difference here. I don't want to rehash it here. (Edit I don't know what your opinion is here, I'm just guessing). Basically there is three type of people here. Some who want strictest type checking TS can offer, some who wants some type checking (don't like all the strict flags), and some who don't want any type-checking. It became pretty clear with this issue #3324. It's fine if you belong to the camp "deno needs not to do any type-checking", I don't take issue with it, it's your view. I just happen to belong to the camp who believes if Deno takes TS in, it should have strictest type checking possible. If we go without type checking TS at all by default, in my opinion, then Deno should not take TS as input files. It should take only JS files in (and strongly encourage for generated I do support however having an |
@Ciantic actually I am more on the side of having type checking by default like tsc is doing. After concerning |
I believe this can be partially solved by not advocating the |
@wongjiahau No, you can see this issue as being about about slow TS compile time for some given dependency graph. Suggesting ways to reduce dependencies is entirely orthogonal to that. |
@nayeemrmn check out this repository where I demonstrated how the |
@wongjiahau if there is a significant difference, we need to investigate that, as there is potentially an inefficiency. Going around posting in every channel you can find to not do a convention that is an effective convention because of an observed performance difference isn't helpful. Logically there should be little to no difference, so the fact that there is potentially one is potentially a bug, not a change to conventions. |
@wongjiahau Your example doesn't have equivalent setups for the two things you're benchmarking, you're actually testing how well Deno can optimise out unused module imports. If you want a fair comparison then you need both |
It’s ok just ignore the benchmark, I’m not going to advocate the new
convention that I wanted to propose anymore, since the community thinks
that the current convention is unquestionable.
…On Tue, 9 Jun 2020 at 7:19 PM, River ***@***.***> wrote:
@wongjiahau <https://github.com/wongjiahau> Your example doesn't have
equivalent setups for the two things you're benchmarking, you're actually
testing how well Deno can optimise out unused module imports.
If you want a fair comparison then you need both x.ts and y.ts to import
the same number of modules. I have the difference at around 10% when I
import all three modules (a, b and c) in both.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#4323 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AFQ4CKGTS27LFKWEK4VIPPTRVYLEZANCNFSM4LGDWSBA>
.
|
The latest Typescript 3.9 might be able to partially solve this issue. Reference https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#speed-improvements |
Deno has 3.9.2 since v1.0 which includes these speed improvements. |
We've got support for incremental compilation now, which mostly alleviates this problem. For further information see #5432 |
Is work being done to improve the compile time? It takes several seconds on every minor change to recompile one file. This slows down the inner loop. Ideally I'd like to see single-file compile time closer to <=200ms.
The text was updated successfully, but these errors were encountered: