perf(ivy): ngcc - avoid unnecessary operations when we only need one format processed (#32003)

Previously, when `ngcc` was called with `compileAllFormats === false`
(i.e. how `@angular/cli` calls it), it would not attempt to process
more properties, once the first was successfully processed. However, it
_would_ continue looping over them and perform some unnecessary
operations, such as:
- Determining the format each property maps to (which can be an
  expensive operation for some properties mapping to either UMD or
  CommonJS).
- Checking whether each property has been processed (which involves
  checking whether any property has been processed with a different
  version of `ngcc` each time).
- Potentially marking properties as processed (which involves a
  file-write operation).

This commit avoids the unnecessary operations by entirely skipping
subsequent properties, once the first one has been successfully
processed. While this theoretically improves performance, it is not
expected to have any noticeable impact in practice, since the list of
`propertiesToConsider` is typically small and the most expensive
operation (marking a property as processed) has low likelihood of
happening (plus these operations are a tiny fraction of `ngcc`'s work).

PR Close #32003
This commit is contained in:
George Kalpakas 2019-08-04 18:31:10 +03:00 committed by Alex Rickabaugh
parent 541ce98432
commit 8e5567d964
1 changed files with 9 additions and 5 deletions

View File

@ -108,9 +108,12 @@ export function mainNgcc(
const entryPointPackageJson = entryPoint.packageJson;
const entryPointPackageJsonPath = fileSystem.resolve(entryPoint.path, 'package.json');
const hasProcessedDts = hasBeenProcessed(entryPointPackageJson, 'typings');
let processDts = !hasBeenProcessed(entryPointPackageJson, 'typings');
for (const property of propertiesToConsider as EntryPointJsonProperty[]) {
// If we only need one format processed and we already have one, exit the loop.
if (!compileAllFormats && (compiledFormats.size > 0)) break;
const formatPath = entryPointPackageJson[property];
const format = getEntryPointFormat(fileSystem, entryPoint, property);
@ -124,12 +127,10 @@ export function mainNgcc(
continue;
}
const isFirstFormat = compiledFormats.size === 0;
const processDts = !hasProcessedDts && isFirstFormat;
// We don't break if this if statement fails because we still want to mark
// the property as processed even if its underlying format has been built already.
if (!compiledFormats.has(formatPath) && (compileAllFormats || isFirstFormat)) {
if (!compiledFormats.has(formatPath)) {
const bundle = makeEntryPointBundle(
fileSystem, entryPoint, formatPath, isCore, property, format, processDts, pathMappings,
true);
@ -148,7 +149,10 @@ export function mainNgcc(
// previous property.
if (compiledFormats.has(formatPath)) {
const propsToMarkAsProcessed = [property];
if (processDts) propsToMarkAsProcessed.push('typings');
if (processDts) {
propsToMarkAsProcessed.push('typings');
processDts = false;
}
markAsProcessed(
fileSystem, entryPointPackageJson, entryPointPackageJsonPath, propsToMarkAsProcessed);