Skip to content

Commit f1afa60

Browse files
roman-garciaclydin
andauthored
perf(@angular/build): read rendered module length once per module in chunk optimizer (#34045)
* perf(@angular/build): read rendered module length once per module in chunk optimizer When converting the chunk optimizer output into an esbuild-compatible metafile, the rendered length of each module was read inside the loop over the module's original inputs. The `renderedLength` property of a rolldown rendered module is a lazy getter that transfers the full module code from native memory on every access. Since each module in this pass is an entire esbuild output chunk, a main chunk of 17 MB with 3,588 inputs resulted in roughly 62 GB of string copies and around 150 seconds spent in `bundleOutputToEsbuildMetafile`, while the rolldown bundling itself took 3 seconds. Read the rendered length once per module before iterating its inputs. The generated metafile is unchanged. On the affected application the `OPTIMIZE_CHUNKS` phase drops from 179 seconds to 4 seconds and the total production build from 234 to 55 seconds. Fixes #34044 * Remove performance comments in chunk-optimizer.ts Removed comments explaining the performance impact of accessing the rendered length in the chunk optimizer. * Update packages/angular/build/src/builders/application/chunk-optimizer.ts Co-authored-by: Charles <19598772+clydin@users.noreply.github.com> --------- Co-authored-by: Charles <19598772+clydin@users.noreply.github.com>
1 parent bc8db5a commit f1afa60

1 file changed

Lines changed: 5 additions & 1 deletion

File tree

packages/angular/build/src/builders/application/chunk-optimizer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,15 @@ function bundleOutputToEsbuildMetafile(
113113
continue;
114114
}
115115

116+
// Read once per module: in Rolldown, `renderedLength` is an uncached getter that
117+
// copies the entire module code across the NAPI bridge on each access.
118+
const { renderedLength } = renderedModule;
119+
116120
for (const [originalInputPath, originalInputInfo] of Object.entries(
117121
originalOutputEntry.inputs,
118122
)) {
119123
const proportion = originalInputInfo.bytesInOutput / totalOriginalBytesInModule;
120-
const newBytesInOutput = Math.floor(renderedModule.renderedLength * proportion);
124+
const newBytesInOutput = Math.floor(renderedLength * proportion);
121125

122126
const existing = newOutputInputs[originalInputPath];
123127
if (existing) {

0 commit comments

Comments
 (0)