Skip to content

Commit 6699cdc

Browse files
committed
perf(@angular/build): fix memory leak in ng serve with i18n
When running `ng serve` with i18n configured, every file save (.html files) triggers a rebuild that creates a new piscina `ThreadPool` for `i18n-inline-worker.js`. Old pools and their worker threads were not properly cleaned up because the inliner was closed prematurely, causing unbounded memory growth. This commit ensures that the inliner is kept open while processing template updates, resolving the issue where orphaned threads were created. Closes #32584 (cherry picked from commit 9d167ca)
1 parent 536a959 commit 6699cdc

File tree

1 file changed

+38
-38
lines changed
  • packages/angular/build/src/builders/application

1 file changed

+38
-38
lines changed

packages/angular/build/src/builders/application/i18n.ts

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -123,48 +123,48 @@ export async function inlineI18n(
123123
inlineResult.prerenderedRoutes = { ...inlineResult.prerenderedRoutes, ...generatedRoutes };
124124
updatedOutputFiles.push(...localeOutputFiles);
125125
}
126-
} finally {
127-
await inliner.close();
128-
}
129126

130-
// Update the result with all localized files.
131-
executionResult.outputFiles = [
132-
// Root and SSR entry files are not modified.
133-
...unModifiedOutputFiles,
134-
// Updated files for each locale.
135-
...updatedOutputFiles,
136-
];
137-
138-
// Assets are only changed if not using the flat output option
139-
if (!i18nOptions.flatOutput) {
140-
executionResult.assetFiles = updatedAssetFiles;
141-
}
142-
143-
// Inline any template updates if present
144-
if (executionResult.templateUpdates?.size) {
145-
// The development server only allows a single locale but issue a warning if used programmatically (experimental)
146-
// with multiple locales and template HMR.
147-
if (i18nOptions.inlineLocales.size > 1) {
148-
inlineResult.warnings.push(
149-
`Component HMR updates can only be inlined with a single locale. The first locale will be used.`,
150-
);
127+
// Update the result with all localized files.
128+
executionResult.outputFiles = [
129+
// Root and SSR entry files are not modified.
130+
...unModifiedOutputFiles,
131+
// Updated files for each locale.
132+
...updatedOutputFiles,
133+
];
134+
135+
// Assets are only changed if not using the flat output option
136+
if (!i18nOptions.flatOutput) {
137+
executionResult.assetFiles = updatedAssetFiles;
151138
}
152-
const firstLocale = [...i18nOptions.inlineLocales][0];
153-
154-
for (const [id, content] of executionResult.templateUpdates) {
155-
const templateUpdateResult = await inliner.inlineTemplateUpdate(
156-
firstLocale,
157-
i18nOptions.locales[firstLocale].translation,
158-
content,
159-
id,
160-
);
161-
executionResult.templateUpdates.set(id, templateUpdateResult.code);
162-
inlineResult.errors.push(...templateUpdateResult.errors);
163-
inlineResult.warnings.push(...templateUpdateResult.warnings);
139+
140+
// Inline any template updates if present
141+
if (executionResult.templateUpdates?.size) {
142+
// The development server only allows a single locale but issue a warning if used programmatically (experimental)
143+
// with multiple locales and template HMR.
144+
if (i18nOptions.inlineLocales.size > 1) {
145+
inlineResult.warnings.push(
146+
`Component HMR updates can only be inlined with a single locale. The first locale will be used.`,
147+
);
148+
}
149+
const firstLocale = [...i18nOptions.inlineLocales][0];
150+
151+
for (const [id, content] of executionResult.templateUpdates) {
152+
const templateUpdateResult = await inliner.inlineTemplateUpdate(
153+
firstLocale,
154+
i18nOptions.locales[firstLocale].translation,
155+
content,
156+
id,
157+
);
158+
executionResult.templateUpdates.set(id, templateUpdateResult.code);
159+
inlineResult.errors.push(...templateUpdateResult.errors);
160+
inlineResult.warnings.push(...templateUpdateResult.warnings);
161+
}
164162
}
165-
}
166163

167-
return inlineResult;
164+
return inlineResult;
165+
} finally {
166+
await inliner.close();
167+
}
168168
}
169169

170170
/**

0 commit comments

Comments
 (0)