Description
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:
-
Not a directly related issue but Document --incremental and composite project APIs #31849 (comment) indicates declaration diagnostics are collected by doing in-memory emit.
-
A different kind of slowness report related to
noEmitOnError
: Compiler API (language service) becomes incredibly slow whennoEmitOnError = true
#24444