Skip to content

Commit 50230a6

Browse files
Addressed feedback and added tracing section.
1 parent 8065c7d commit 50230a6

File tree

1 file changed

+74
-11
lines changed

1 file changed

+74
-11
lines changed

Performance.md

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,18 @@ TypeScript provides the option to skip type-checking of the `.d.ts` files that i
100100

101101
Alternatively, you can also enable the `skipLibCheck` flag to skip checking *all* `.d.ts` files in a compilation.
102102

103-
These two options can often hide misconfiguration and conflicts in `.d.ts` files, so we suggest using them sparingly.
103+
These two options can often hide misconfiguration and conflicts in `.d.ts` files, so we suggest using them *only* for faster builds.
104104

105105
# Configuring Other Build Tools
106106

107107
TypeScript compilation is often performed with other build tools in mind - especially when writing web apps that might involve a bundler.
108108
While we can only make suggestions for a few build tools, ideally these techniques can be generalized.
109109

110+
Make sure that in addition to reading this section, you read up about performance in your choice of build tool - for example:
111+
112+
* [ts-loader's section on *Faster Builds*](https://github.com/TypeStrong/ts-loader#faster-builds)
113+
* [awesome-typescript-loader's section on *Performance Issues*](https://github.com/s-panferov/awesome-typescript-loader/blob/master/README.md#performance-issues)
114+
110115
## Concurrent Type-Checking
111116

112117
Type-checking typically requires semantic information from other files, and can be relatively expensive compared to other steps like emitting.
@@ -115,7 +120,7 @@ Because type-checking can take a little bit longer, it can impact the inner deve
115120
For this reason, some build tools can run type-checking in a concurrent process without blocking emit.
116121
While this means that invalid code can run before TypeScript reports an error in the tool, you'll often see errors in your editor first, and you won't be blocked for as long from running working code.
117122

118-
An example of this in action is Webpack's `fork-ts-checker` plugin.
123+
An example of this in action is the [`fork-ts-checker-webpack-plugin`](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin) plugin for Webpack, or [awesome-typescript-loader](https://github.com/s-panferov/awesome-typescript-loader) which also sometimes does this.
119124

120125
## Isolated File Emit
121126

@@ -125,14 +130,35 @@ But needing to check other files to emit of an arbitrary file can make emit slow
125130

126131
The need for features that need non-local information is somewhat rare - regular `enum`s can be used in place of `const enum`s, and modules can be used instead of `namespace`s.
127132
For that reason, TypeScript provides the `isolatedModules` flag to warn when using them.
128-
Using `isolatedModules` means that your codebase is safe for tools to use TypeScript APIs like `transpileModule` or alternative compilers like Babel.
133+
Enabling `isolatedModules` means that your codebase is safe for tools to use TypeScript APIs like `transpileModule` or alternative compilers like Babel.
134+
135+
If you *don't* turn `isolatedModules` on, then using build tools cannot properly transform code using isolated file emit techniques.
136+
As an example, the following code won't properly work at runtime because `const enum` values are expected to be inlined.
137+
138+
```ts
139+
// ./src/fileA.ts
140+
141+
export const enum E {
142+
A = 0,
143+
B = 1,
144+
}
145+
146+
// ./src/fileB.ts
129147

130-
As an example of this in action, ts-loader provides
148+
import { E } from "./fileA";
131149

132-
* the `transpileOnly` flag to use `transpileModule`.
133-
* the `useBabel` flag
150+
console.log(E.A);
151+
```
152+
153+
Isolated file emit can be leveraged by using the following tools:
134154

135-
<!-- TODO -->
155+
* [ts-loader](https://github.com/TypeStrong/ts-loader) provides [a `transpileOnly` flag](https://github.com/TypeStrong/ts-loader#transpileonly-boolean-defaultfalse) which performs isolated file emit by using `transpileModule`.
156+
* [awesome-typescript-loader](https://github.com/s-panferov/awesome-typescript-loader) provides [a `transpileOnly` flag](https://github.com/s-panferov/awesome-typescript-loader/blob/master/README.md#transpileonly-boolean) which performs isolated file emit by using `transpileModule`.
157+
* [TypeScript's `transpileModule` API](https://github.com/microsoft/TypeScript/blob/a685ac426c168a9d8734cac69202afc7cb022408/lib/typescript.d.ts#L5866) can be used directly.
158+
* [awesome-typescript-loader provides the `useBabel` flag](https://github.com/s-panferov/awesome-typescript-loader/blob/master/README.md#usebabel-boolean-defaultfalse).
159+
* [babel-loader](https://github.com/babel/babel-loader) compiles files in an isolated manner (but does not provide type-checking on its own).
160+
* [gulp-typescript](https://www.npmjs.com/package/gulp-typescript) enables isolated file emit when `isolatedModules` is enabled.
161+
* [rollup-plugin-typescript](https://github.com/rollup/rollup-plugin-typescript) ***only*** performs isolated file compilation.
136162

137163
# Investigating Issues
138164

@@ -274,6 +300,8 @@ Accessors are only available when targeting ECMAScript 5 and higher.
274300

275301
# Filing an Issue
276302

303+
If your project is already properly and optimally configured, you may want to [file an issue](https://github.com/microsoft/TypeScript/issues/new/choose).
304+
277305
The best reports of performance issues contain *easily obtainable* and *minimal* reproductions of the problem.
278306
In other words, a codebase that can easily be cloned over git that contains only a few files.
279307
They require either no external integration with build tools - they can either be invoked via `tsc` or use isolated code which consumes the TypeScript API.
@@ -282,9 +310,44 @@ Codebases that require complex invocations and setups cannot be prioritized.
282310
We understand that this is not always easy to achieve - specifically, because it is hard to isolate the source of a problem within a codebase, and because sharing intellectual property may be an issue.
283311
In some cases, the team will be willing to send a non-disclosure agreement if we believe the issue is highly impactful.
284312

285-
Aside from that, here are some other things a performance issue report should provide.
313+
Regardless of whether a reproduction is possible, following these directions when filing issues will help us provide you with performance fixes.
314+
315+
## Reporting Compiler Performance Issues
316+
317+
Sometimes you'll witness performance issues in both build times as well as editing scenarios.
318+
In these cases, it's best to focus on the TypeScript compiler.
319+
320+
First, a nightly version of TypeScript should be used to ensure you're not hitting a resolved issue:
321+
322+
```sh
323+
npm install --save-dev typescript@next
324+
325+
# or
326+
327+
yarn add typescript@next --dev
328+
```
329+
330+
A compiler perf issue should include
331+
332+
* The version of TypeScript that was installed (i.e. `npx tsc -v` or `yarn tsc -v`)
333+
* The output of running with `extendedDiagnostics` (`tsc --extendedDiagnostics -p tsconfig.json`)
334+
* Ideally, a project that demonstrates the issues being encountered.
335+
* Output logs from profiling the compiler (`isolate-*-*-*.log` and `*.cpuprofile` files)
336+
337+
### Profiling the Compiler
338+
339+
It is important to provide the team with diagnostic traces by running Node.js with the `--trace-ic` flag alongside TypeScript with the `--generateCpuProfile` flag:
340+
341+
```sh
342+
node --trace-ic ./node_modules/typescript/lib/tsc.js --generateCpuProfile profile.cpuprofile -p tsconfig.json
343+
```
344+
345+
Here `./node_modules/typescript/lib/tsc.js` can be replaced with any path to where your version of the TypeScript compiler is installed, and `tsconfig.json` can be any TypeScript configuration file.
346+
`profile.cpuprofile` is an output file of your choice.
347+
348+
This will generate two files:
286349

287-
* `extendedDiagnostics` output
288-
*
350+
* `--trace-ic` will emit to a file of the `isolate-*-*-*.log` (e.g. `isolate-00000176DB2DF130-17676-v8.log`).
351+
* `--generateCpuProfile` will emit to a file with the name of your choice. In the above example, it will be a file named `profile.cpuprofile`.
289352

290-
<!-- TODO -->
353+
Both of these files are readable as plain-text, and you can modify them before attaching them as part of a GitHub issue. (e.g. to scrub them of file paths that may expose internal-only information).

0 commit comments

Comments
 (0)