perf(ivy): basic incremental compilation for ngtsc (#29380)
This commit introduces a mechanism for incremental compilation to the ngtsc compiler. Previously, incremental information was used in the construction of the ts.Program for subsequent compilations, but was not used in ngtsc itself. This commit adds an IncrementalState class, which tracks state between ngtsc compilations. Currently, this supports skipping the TypeScript emit step when the compiler can prove the contents of emit have not changed. This is implemented for @Injectables as well as for files which don't contain any Angular decorated types. These are the only files which can be proven to be safe today. See ngtsc/incremental/README.md for more details. PR Close #29380
This commit is contained in:

committed by
Jason Aden

parent
7316212c1e
commit
7041e61562
@ -18,6 +18,7 @@ import {CycleAnalyzer, ImportGraph} from './cycles';
|
||||
import {ErrorCode, ngErrorCode} from './diagnostics';
|
||||
import {FlatIndexGenerator, ReferenceGraph, checkForPrivateExports, findFlatIndexEntryPoint} from './entry_point';
|
||||
import {AbsoluteModuleStrategy, AliasGenerator, AliasStrategy, DefaultImportTracker, FileToModuleHost, FileToModuleStrategy, ImportRewriter, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, NoopImportRewriter, R3SymbolsImportRewriter, Reference, ReferenceEmitter} from './imports';
|
||||
import {IncrementalState} from './incremental';
|
||||
import {PartialEvaluator} from './partial_evaluator';
|
||||
import {AbsoluteFsPath, LogicalFileSystem} from './path';
|
||||
import {NOOP_PERF_RECORDER, PerfRecorder, PerfTracker} from './perf';
|
||||
@ -60,6 +61,7 @@ export class NgtscProgram implements api.Program {
|
||||
private defaultImportTracker: DefaultImportTracker;
|
||||
private perfRecorder: PerfRecorder = NOOP_PERF_RECORDER;
|
||||
private perfTracker: PerfTracker|null = null;
|
||||
private incrementalState: IncrementalState;
|
||||
|
||||
constructor(
|
||||
rootNames: ReadonlyArray<string>, private options: api.CompilerOptions,
|
||||
@ -143,6 +145,13 @@ export class NgtscProgram implements api.Program {
|
||||
this.moduleResolver = new ModuleResolver(this.tsProgram, options, this.host);
|
||||
this.cycleAnalyzer = new CycleAnalyzer(new ImportGraph(this.moduleResolver));
|
||||
this.defaultImportTracker = new DefaultImportTracker();
|
||||
if (oldProgram === undefined) {
|
||||
this.incrementalState = IncrementalState.fresh();
|
||||
} else {
|
||||
const oldNgtscProgram = oldProgram as NgtscProgram;
|
||||
this.incrementalState = IncrementalState.reconcile(
|
||||
oldNgtscProgram.incrementalState, oldNgtscProgram.tsProgram, this.tsProgram);
|
||||
}
|
||||
}
|
||||
|
||||
getTsProgram(): ts.Program { return this.tsProgram; }
|
||||
@ -332,6 +341,10 @@ export class NgtscProgram implements api.Program {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.incrementalState.safeToSkipEmit(targetSourceFile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const fileEmitSpan = this.perfRecorder.start('emitFile', targetSourceFile);
|
||||
emitResults.push(emitCallback({
|
||||
targetSourceFile,
|
||||
@ -440,8 +453,8 @@ export class NgtscProgram implements api.Program {
|
||||
];
|
||||
|
||||
return new IvyCompilation(
|
||||
handlers, checker, this.reflector, this.importRewriter, this.perfRecorder,
|
||||
this.sourceToFactorySymbols);
|
||||
handlers, checker, this.reflector, this.importRewriter, this.incrementalState,
|
||||
this.perfRecorder, this.sourceToFactorySymbols);
|
||||
}
|
||||
|
||||
private get reflector(): TypeScriptReflectionHost {
|
||||
|
Reference in New Issue
Block a user