Skip to content

Commit a2dcb23

Browse files
committed
refactor(@angular/build): streamline cache check resolution in i18n inliner
Streamline the asynchronous cache resolution in inlineAll by removing the intermediate CacheCheckItem interface and array mapping allocations. Results are now assigned directly to fileResultsByLocale on hit or pushed to uncachedByFile on miss. When no persistent cache is configured, a fast path directly queues uncached files without promise or hash overhead.
1 parent 799f332 commit a2dcb23

1 file changed

Lines changed: 48 additions & 71 deletions

File tree

packages/angular/build/src/tools/esbuild/i18n-inliner.ts

Lines changed: 48 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -131,31 +131,6 @@ interface TransformedFileResult {
131131
messages: { type: 'error' | 'warning'; message: string }[];
132132
}
133133

134-
/**
135-
* Represents an in-flight asynchronous cache lookup for a single (file x locale) transformation.
136-
*/
137-
interface CacheCheckItem {
138-
/**
139-
* The relative file path of the JavaScript file to transform.
140-
*/
141-
filename: string;
142-
143-
/**
144-
* The locale specifier being targeted for translation.
145-
*/
146-
locale: string;
147-
148-
/**
149-
* The computed cache key hash, or undefined if persistent caching is not configured.
150-
*/
151-
cacheKey: string | undefined;
152-
153-
/**
154-
* A promise that resolves to the cached transform result, or null if uncached or on lookup failure.
155-
*/
156-
cachedResult: Promise<TransformedFileResult | null>;
157-
}
158-
159134
/**
160135
* An uncached transformation request entry for a file within a specific locale.
161136
*/
@@ -306,68 +281,70 @@ export class I18nInliner {
306281
}),
307282
);
308283

309-
const cacheChecks: CacheCheckItem[] = [];
284+
const uncachedByFile = new Map<string, UncachedLocaleEntry[]>();
310285

311-
for (const filename of filenames) {
312-
const file = this.#localizeFiles.get(filename);
313-
assert(file !== undefined, 'Localize file must exist: ' + filename);
286+
if (this.#transformedFileCache) {
287+
const cacheChecks: Promise<void>[] = [];
314288

315-
for (const { locale } of windowLocales) {
316-
let cacheKey: string | undefined;
317-
let cachedResultPromise: Promise<TransformedFileResult | null> = Promise.resolve(null);
289+
for (const filename of filenames) {
290+
const file = this.#localizeFiles.get(filename);
291+
assert(file !== undefined, 'Localize file must exist: ' + filename);
292+
293+
const fileEntries: UncachedLocaleEntry[] = [];
318294

319-
if (this.#transformedFileCache) {
295+
for (const { locale } of windowLocales) {
320296
const fileCacheKeyBase = localeCacheBases.get(locale);
321297
assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale);
322298

323299
const hasher = createContentHash();
324300
hasher.update(file.hash);
325301
hasher.update(filename);
326302
hasher.update(fileCacheKeyBase);
327-
cacheKey = hasher.digest();
328-
329-
cachedResultPromise = this.#transformedFileCache
330-
.get(cacheKey)
331-
.then((val) => val ?? null)
332-
.catch(() => null);
303+
const cacheKey = hasher.digest();
304+
305+
cacheChecks.push(
306+
this.#transformedFileCache
307+
.get(cacheKey)
308+
.then((result) => {
309+
if (result) {
310+
fileResultsByLocale.get(locale)?.set(filename, result);
311+
} else {
312+
fileEntries.push({
313+
locale,
314+
cacheKey,
315+
translation: localeBlobs.get(locale),
316+
});
317+
}
318+
})
319+
.catch(() => {
320+
fileEntries.push({
321+
locale,
322+
cacheKey,
323+
translation: localeBlobs.get(locale),
324+
});
325+
}),
326+
);
333327
}
334328

335-
cacheChecks.push({
336-
filename,
337-
locale,
338-
cacheKey,
339-
cachedResult: cachedResultPromise,
340-
});
329+
uncachedByFile.set(filename, fileEntries);
341330
}
342-
}
343-
344-
// Await all cache checks for this window
345-
const resolvedChecks = await Promise.all(
346-
cacheChecks.map(async (item) => ({
347-
...item,
348-
result: await item.cachedResult,
349-
})),
350-
);
351331

352-
// Group uncached items by filename for this window
353-
const uncachedByFile = new Map<string, UncachedLocaleEntry[]>();
332+
await Promise.all(cacheChecks);
354333

355-
for (const item of resolvedChecks) {
356-
if (item.result) {
357-
// Cache hit: store directly in locale file results
358-
fileResultsByLocale.get(item.locale)?.set(item.filename, item.result);
359-
} else {
360-
// Cache miss: needs worker processing
361-
let fileEntries = uncachedByFile.get(item.filename);
362-
if (!fileEntries) {
363-
fileEntries = [];
364-
uncachedByFile.set(item.filename, fileEntries);
334+
for (const [filename, entries] of uncachedByFile) {
335+
if (entries.length === 0) {
336+
uncachedByFile.delete(filename);
365337
}
366-
fileEntries.push({
367-
locale: item.locale,
368-
cacheKey: item.cacheKey,
369-
translation: localeBlobs.get(item.locale),
370-
});
338+
}
339+
} else {
340+
for (const filename of filenames) {
341+
uncachedByFile.set(
342+
filename,
343+
windowLocales.map(({ locale }) => ({
344+
locale,
345+
translation: localeBlobs.get(locale),
346+
})),
347+
);
371348
}
372349
}
373350

0 commit comments

Comments
 (0)