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

Slow incremental compilation when noEmitOnError is true #37867

Closed
mkubilayk opened this issue Apr 9, 2020 · 5 comments
Closed

Slow incremental compilation when noEmitOnError is true #37867

mkubilayk opened this issue Apr 9, 2020 · 5 comments
Assignees
Labels
Bug A bug in TypeScript

Comments

@mkubilayk
Copy link
Contributor

mkubilayk commented Apr 9, 2020

TypeScript Version: 3.8.3

Search Terms: slow compilation, slow incremental compilation, declaration diagnostics, slow noEmitOnError

Code

I'm trying to debug why incremental TypeScript compilation is slow on my project when using noEmitOnError option. A clean compilation takes around 12s and an incremental compilation after a simple change takes around 10s. Turning off noEmitOnError takes the incremental compilation time down to 1.6s.

Based on the CPU profiles, it looks like bulk of the time is spent in getDeclarationDiagnostics, which is only triggered pre-emit when noEmitOnError is turned on.

tsconfig.json:

{
    "compilerOptions": {
        "allowSyntheticDefaultImports": true,
        "target": "ESNext",
        "importHelpers": false,
        "module": "esnext",
        "jsx": "react",
        "newLine": "lf",
        "moduleResolution": "Node",
        "strict": true,
        "noErrorTruncation": true,
        "noLib": true,
        "preserveConstEnums": true,
        "resolveJsonModule": true,
        "sourceMap": true,
        "noResolve": false,
        "typeRoots": [],
        "alwaysStrict": true,
        "declaration": true,
        "isolatedModules": true,
        "composite": true
    },
    "include": [
        "**/*.ts",
        "**/*.tsx"
    ],
    "exclude": [
        "node_modules"
    ]
}

Using tsc --incremental --noEmitOnError and tsc --incremental:

Diagnostics:

Clean noEmitOnError true Incremental noEmitOnError true Clean noEmitOnError false Incremental noEmitOnError false
Total time 12.34s 9.90s 13.31s 1.63s
CPU Profile Link Link Link Link
Files 294 294 294 294
Lines 61074 61075 61074 61075
Nodes 220691 220694 220691 220694
Identifiers 69349 69350 69349 69350
Symbols 191258 184217 191182 46246
Types 84567 81264 84493 103
Memory used 225553K 205273K 226985K 92313K
Assignability cache size 127401 127401 127401 2
Identity cache size 1820 1820 1820 0
Subtype cache size 1203 1204 1203 0
Strict subtype cache size 10236 5766 10236 0
I/O Read time 0.15s 0.15s 0.04s 0.03s
Parse time 0.81s 0.85s 0.96s 0.78s
Program time 1.15s 1.17s 1.21s 0.97s
Bind time 0.56s 0.63s 0.64s 0.55s
Check time 7.96s 8.02s 8.41s 0.03s
transformTime time 0.96s 0.31s 0.93s 0.01s
commentTime time 0.18s 0.00s 0.24s 0.00s
printTime time 2.66s 0.08s 3.03s 0.07s
Emit time 2.67s 0.08s 3.04s 0.07s
Source Map time 0.10s 0.00s 0.13s 0.00s
I/O Write time 0.26s 0.01s 0.25s 0.00s

Please remove .txt extension from CPU profiles to be able to load them in Chrome dev tools. I had to use .txt extension to be able to attach them to the issue.

Expected behavior:

Enabling noEmitOnError should not signficantly increase incremental compilation time. In the project above, I would expect a simple incremental compilation to take 1-2 seconds, i.e. similar to when noEmitOnError is false.

Actual behavior:

Incremental compilation after a simple change takes around 10 seconds, which is almost the same as the 12 seconds it takes to perform a clean compilation.

Playground Link: -

Related Issues:

@mkubilayk mkubilayk changed the title Slow incremental compilation when noEmitOnError is true Slow incremental compilation when noEmitOnError is true Apr 9, 2020
@sheetalkamat sheetalkamat added the Bug A bug in TypeScript label Apr 9, 2020
@sheetalkamat sheetalkamat self-assigned this Apr 9, 2020
@sheetalkamat
Copy link
Member

Should look into writing tsbuildinfo file when there are errors with noEmitOnError so semantic errors are cached.. Needs more depth investigation since this affects --build as well

@timocov
Copy link
Contributor

timocov commented Apr 13, 2020

I also ran into the issue (in my case it increases the re-compilation time in watch mode from 25 to ~70 seconds). Please ping me if I need to provide any additional information.

@timocov
Copy link
Contributor

timocov commented Apr 15, 2020

I should say that disabling declaration compiler option speeds up the build as well as disabling noEmitOnError in my case.

Diagnostics (in watch mode, incremental build):

Name declaration: false declaration: true
Files 3944 3944
Lines 460896 460896
Nodes 1966966 1966966
Identifiers 654712 654712
Symbols 307304 856053
Types 1150 342100
Memory used 696512K 1552378K
I/O read 0.00s 0.00s
I/O write 0.01s 0.00s
Parse time 0.15s 0.22s
Bind time 0.04s 0.02s
Check time 0.45s 41.94s
Emit time 0.96s 0.00s
Total time 1.60s 42.18s

Cpu profile for declaration: false: declaration-disabled.zip

Cpu profile for declaration: true: declaration-enabled.zip

@sheetalkamat
Copy link
Member

Should be fixed by #38853

@robpalme
Copy link

robpalme commented Jun 3, 2020

Thank you @sheetalkamat. "noEmitOnError" is a popular feature, so your fix hugely improves performance for many users.

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

No branches or pull requests

4 participants