Skip to content

Commit

Permalink
perf(@ngtools/webpack): reduce resource processing during JIT initial…
Browse files Browse the repository at this point in the history
… lazy route analysis

During JIT mode, deprecated string-form lazy routes are discovered by analyzing the application via the compiler-cli.
This process, however, does not need any of the component resources nor does the CLI need to load them. In JIT mode,
a no-op resource loader is now used that will provide the compiler with blank templates and styles. This can greatly
reduce the amount of processing required during an initial JIT build, especially for large projects.
  • Loading branch information
clydin committed Mar 22, 2021
1 parent 69f636f commit cc3cc8d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
4 changes: 2 additions & 2 deletions packages/ngtools/webpack/src/ivy/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import { createHash } from 'crypto';
import * as path from 'path';
import * as ts from 'typescript';
import { NgccProcessor } from '../ngcc_processor';
import { WebpackResourceLoader } from '../resource_loader';
import { ResourceLoader } from '../resource_loader';
import { normalizePath } from './paths';

export function augmentHostWithResources(
host: ts.CompilerHost,
resourceLoader: WebpackResourceLoader,
resourceLoader: ResourceLoader,
options: { directTemplateLoading?: boolean } = {},
) {
const resourceHost = host as CompilerHost;
Expand Down
11 changes: 7 additions & 4 deletions packages/ngtools/webpack/src/ivy/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import { findLazyRoutes } from '../lazy_routes';
import { NgccProcessor } from '../ngcc_processor';
import { TypeScriptPathsPlugin } from '../paths-plugin';
import { WebpackResourceLoader } from '../resource_loader';
import { NoopResourceLoader, ResourceLoader, WebpackResourceLoader } from '../resource_loader';
import { addError, addWarning } from '../webpack-diagnostics';
import { isWebpackFiveOrHigher, mergeResolverMainFields } from '../webpack-version';
import { SourceFileCache } from './cache';
Expand Down Expand Up @@ -158,7 +158,9 @@ export class AngularWebpackPlugin {
});

let ngccProcessor: NgccProcessor | undefined;
const resourceLoader = new WebpackResourceLoader();
const resourceLoader = this.pluginOptions.jitMode
? new NoopResourceLoader()
: new WebpackResourceLoader();
let previousUnused: Set<string> | undefined;
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (thisCompilation) => {
const compilation = thisCompilation as WebpackCompilation;
Expand Down Expand Up @@ -231,7 +233,8 @@ export class AngularWebpackPlugin {
// Setup resource loading
resourceLoader.update(compilation, changedFiles);
augmentHostWithResources(host, resourceLoader, {
directTemplateLoading: this.pluginOptions.directTemplateLoading,
directTemplateLoading:
!this.pluginOptions.jitMode && this.pluginOptions.directTemplateLoading,
});

// Setup source file adjustment options
Expand Down Expand Up @@ -403,7 +406,7 @@ export class AngularWebpackPlugin {
rootNames: string[],
host: CompilerHost,
diagnosticsReporter: DiagnosticsReporter,
resourceLoader: WebpackResourceLoader,
resourceLoader: ResourceLoader,
) {
// Create the Angular specific program that contains the Angular compiler
const angularProgram = new NgtscProgram(
Expand Down
28 changes: 28 additions & 0 deletions packages/ngtools/webpack/src/resource_loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ import * as vm from 'vm';
import { RawSource } from 'webpack-sources';
import { normalizePath } from './ivy/paths';

export interface ResourceLoader {
get(file: string): Promise<string>;
getModifiedResourceFiles(): Set<string>;
getResourceDependencies(file: string): Iterable<string>;
setAffectedResources(file: string, resources: Iterable<string>): void;
update(
parentCompilation: import('webpack').compilation.Compilation,
changedFiles?: Iterable<string>,
): void;
}

const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
Expand All @@ -25,6 +36,23 @@ interface CompilationOutput {
success: boolean;
}

export class NoopResourceLoader implements ResourceLoader {
async get(): Promise<string> {
return '';
}

getModifiedResourceFiles(): Set<string> {
return new Set();
}

getResourceDependencies(): Iterable<string> {
return [];
}

setAffectedResources(): void {}
update(): void {}
}

export class WebpackResourceLoader {
private _parentCompilation: any;
private _fileDependencies = new Map<string, Set<string>>();
Expand Down

0 comments on commit cc3cc8d

Please sign in to comment.