Skip to content

Commit

Permalink
perf(ngcc): shortcircuit tokenizing in ESM dependency host (#37639)
Browse files Browse the repository at this point in the history
This dependency host tokenizes files to identify all the imported
paths. This commit calculates the last place in the source code
where there can be an import path; it then exits the tokenization
when we get to this point in the file.

Testing with a reasonably large project showed that the tokenizer
spends about 2/3 as much time scanning files. For example in a
"noop" hot run of ngcc using the program-based entry-point
finder the percentage of time spent in the `scan()` function of
the TS tokenizer goes down from 9.9% to 6.6%.

PR Close #37639
  • Loading branch information
petebacondarwin authored and mhevery committed Jun 18, 2020
1 parent d0437b3 commit bd7f440
Showing 1 changed file with 7 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ export class EsmDependencyHost extends DependencyHostBase {
const templateStack: ts.SyntaxKind[] = [];
let lastToken: ts.SyntaxKind = ts.SyntaxKind.Unknown;
let currentToken: ts.SyntaxKind = ts.SyntaxKind.Unknown;
const stopAtIndex = findLastPossibleImportOrReexport(fileContents);

this.scanner.setText(fileContents);

while ((currentToken = this.scanner.scan()) !== ts.SyntaxKind.EndOfFileToken) {
if (this.scanner.getTokenPos() > stopAtIndex) {
break;
}
switch (currentToken) {
case ts.SyntaxKind.TemplateHead:
// TemplateHead indicates the beginning of a backticked string
Expand Down Expand Up @@ -266,6 +270,9 @@ export function hasImportOrReexportStatements(source: string): boolean {
return /(?:import|export)[\s\S]+?(["'])(?:\\\1|.)+?\1/.test(source);
}

function findLastPossibleImportOrReexport(source: string): number {
return Math.max(source.lastIndexOf('import'), source.lastIndexOf(' from '));
}

/**
* Check whether the given statement is an import with a string literal module specifier.
Expand Down

0 comments on commit bd7f440

Please sign in to comment.