perf(compiler-cli): split Ivy template type-checking into multiple files (#36211)

As a performance optimization, this commit splits the single
__ngtypecheck__.ts file which was previously added to the user's program as
a container for all template type-checking code into multiple .ngtypecheck
shim files, one for each original file in the user's program.

In larger applications, the generation, parsing, and checking of this single
type-checking file was a huge performance bottleneck, with the file often
exceeding 1 MB in text content. Particularly in incremental builds,
regenerating this single file for the entire application proved especially
expensive.

This commit introduces a new strategy for template type-checking code which
makes use of a new interface, the `TypeCheckingProgramStrategy`. This
interface abstracts the process of creating a new `ts.Program` to type-check
a particular compilation, and allows the mechanism there to be kept separate
from the more complex logic around dealing with multiple .ngtypecheck files.

A new `TemplateTypeChecker` hosts that logic and interacts with the
`TypeCheckingProgramStrategy` to actually generate and return diagnostics.
The `TypeCheckContext` class, previously the workhorse of template type-
checking, is now solely focused on collecting and generating type-checking
file contents.

A side effect of implementing the new `TypeCheckingProgramStrategy` in this
way is that the API is designed to be suitable for use by the Angular
Language Service as well. The LS also needs to type-check components, but
has its own method for constructing a `ts.Program` with type-checking code.

Note that this commit does not make the actual checking of templates at all
_incremental_ just yet. That will happen in a future commit.

PR Close #36211
This commit is contained in:
Alex Rickabaugh
2020-03-04 15:50:12 -08:00
parent 4213e8d5f0
commit b861e9c0ac
27 changed files with 589 additions and 198 deletions

View File

@ -12,11 +12,11 @@ import * as ts from 'typescript';
import * as api from '../transformers/api';
import {verifySupportedTypeScriptVersion} from '../typescript_support';
import {NgCompilerHost} from './core';
import {NgCompiler, NgCompilerHost} from './core';
import {NgCompilerOptions} from './core/api';
import {NgCompiler} from './core/src/compiler';
import {IndexedComponent} from './indexer';
import {NOOP_PERF_RECORDER, PerfRecorder, PerfTracker} from './perf';
import {ReusedProgramStrategy} from './typecheck';
@ -74,9 +74,12 @@ export class NgtscProgram implements api.Program {
this.host.postProgramCreationCleanup();
const reusedProgramStrategy = new ReusedProgramStrategy(
this.tsProgram, this.host, this.options, this.host.shimExtensionPrefixes);
// Create the NgCompiler which will drive the rest of the compilation.
this.compiler =
new NgCompiler(this.host, options, this.tsProgram, reuseProgram, this.perfRecorder);
this.compiler = new NgCompiler(
this.host, options, this.tsProgram, reusedProgramStrategy, reuseProgram, this.perfRecorder);
}
getTsProgram(): ts.Program {