mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-18 11:44:05 +08:00
perf(@ngtools/webpack): cache results of processed inline resources
When in watch mode, both the file and inline resources will now be cached between rebuilds. This removes the need to reprocess inline resources that have not changed even if the containing TypeScript file has changed.
This commit is contained in:
parent
d92805e361
commit
8dfc8e73f3
@ -150,7 +150,7 @@ export class AngularWebpackPlugin {
|
||||
});
|
||||
|
||||
let ngccProcessor: NgccProcessor | undefined;
|
||||
const resourceLoader = new WebpackResourceLoader();
|
||||
let resourceLoader: WebpackResourceLoader | undefined;
|
||||
let previousUnused: Set<string> | undefined;
|
||||
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (thisCompilation) => {
|
||||
const compilation = thisCompilation as WebpackCompilation;
|
||||
@ -164,6 +164,11 @@ export class AngularWebpackPlugin {
|
||||
// Store watch mode; assume true if not present (webpack < 4.23.0)
|
||||
this.watchMode = compiler.watchMode ?? true;
|
||||
|
||||
// Initialize the resource loader if not already setup
|
||||
if (!resourceLoader) {
|
||||
resourceLoader = new WebpackResourceLoader(this.watchMode);
|
||||
}
|
||||
|
||||
// Initialize and process eager ngcc if not already setup
|
||||
if (!ngccProcessor) {
|
||||
const { processor, errors, warnings } = initializeNgccProcessor(
|
||||
@ -266,7 +271,7 @@ export class AngularWebpackPlugin {
|
||||
await this.rebuildRequiredFiles(modules, compilation, fileEmitter);
|
||||
|
||||
// Clear out the Webpack compilation to avoid an extra retaining reference
|
||||
resourceLoader.clearParentCompilation();
|
||||
resourceLoader?.clearParentCompilation();
|
||||
|
||||
// Analyze program for unused files
|
||||
if (compilation.errors.length > 0) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import { createHash } from 'crypto';
|
||||
import * as vm from 'vm';
|
||||
import { Compilation, EntryPlugin, NormalModule, library, node, sources } from 'webpack';
|
||||
import { normalizePath } from './ivy/paths';
|
||||
@ -20,10 +21,18 @@ export class WebpackResourceLoader {
|
||||
private _fileDependencies = new Map<string, Set<string>>();
|
||||
private _reverseDependencies = new Map<string, Set<string>>();
|
||||
|
||||
private cache = new Map<string, CompilationOutput>();
|
||||
private fileCache?: Map<string, CompilationOutput>;
|
||||
private inlineCache?: Map<string, CompilationOutput>;
|
||||
private modifiedResources = new Set<string>();
|
||||
private outputPathCounter = 1;
|
||||
|
||||
constructor(shouldCache: boolean) {
|
||||
if (shouldCache) {
|
||||
this.fileCache = new Map();
|
||||
this.inlineCache = new Map();
|
||||
}
|
||||
}
|
||||
|
||||
update(
|
||||
parentCompilation: Compilation,
|
||||
changedFiles?: Iterable<string>,
|
||||
@ -35,12 +44,12 @@ export class WebpackResourceLoader {
|
||||
if (changedFiles) {
|
||||
for (const changedFile of changedFiles) {
|
||||
for (const affectedResource of this.getAffectedResources(changedFile)) {
|
||||
this.cache.delete(normalizePath(affectedResource));
|
||||
this.fileCache?.delete(normalizePath(affectedResource));
|
||||
this.modifiedResources.add(affectedResource);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.cache.clear();
|
||||
this.fileCache?.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,15 +245,15 @@ export class WebpackResourceLoader {
|
||||
|
||||
async get(filePath: string): Promise<string> {
|
||||
const normalizedFile = normalizePath(filePath);
|
||||
let compilationResult = this.cache.get(normalizedFile);
|
||||
let compilationResult = this.fileCache?.get(normalizedFile);
|
||||
|
||||
if (compilationResult === undefined) {
|
||||
// cache miss so compile resource
|
||||
compilationResult = await this._compile(filePath);
|
||||
|
||||
// Only cache if compilation was successful
|
||||
if (compilationResult.success) {
|
||||
this.cache.set(normalizedFile, compilationResult);
|
||||
if (this.fileCache && compilationResult.success) {
|
||||
this.fileCache.set(normalizedFile, compilationResult);
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,7 +265,16 @@ export class WebpackResourceLoader {
|
||||
return '';
|
||||
}
|
||||
|
||||
const compilationResult = await this._compile(undefined, data, mimeType);
|
||||
const cacheKey = createHash('md5').update(data).digest('hex');
|
||||
let compilationResult = this.inlineCache?.get(cacheKey);
|
||||
|
||||
if (compilationResult === undefined) {
|
||||
compilationResult = await this._compile(undefined, data, mimeType);
|
||||
|
||||
if (this.inlineCache && compilationResult.success) {
|
||||
this.inlineCache.set(cacheKey, compilationResult);
|
||||
}
|
||||
}
|
||||
|
||||
return compilationResult.content;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user