Spread operator slow with `application` builder
Which @angular/* package(s) are the source of the bug?
compiler
Is this a regression?
No
Description
Hello, I noticed that the spread operator is significantly slower (sometimes more than 2x slower) when using vite instead of webpack. This doubles the loading time of some of our components.
In my minimal reproduction, I get an average of 10ms with webpack and 35ms with vite, with both firefox and chrome.
Is this indeed an issue with angular and is there any way to fix it?
Thank you
Please provide a link to a minimal reproduction of the bug
https://github.com/jopelle1/repro-angular-vite
Please provide the environment you discovered this bug in (run ng version)
Angular CLI: 17.3.11
Node: 18.20.4
Package Manager: npm 10.8.2
OS: linux x64
Angular: 17.3.12
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1703.11
@angular-devkit/build-angular 17.3.11
@angular-devkit/core 17.3.11
@angular-devkit/schematics 17.3.11
@angular/cli 17.3.11
@schematics/angular 17.3.11
rxjs 7.8.1
typescript 5.4.5
zone.js 0.14.10
Anything else?
No response
Your repro is in v17 but I can also reproduce it in v19.
This is due to the downleveling of native spread by this code. Which mentions this Chromium performance issue : https://issues.chromium.org/u/1/issues/42201529?pli=1
Fwiw, by running the perf test provided in the issue :
runTest() {
const now = performance.now();
const a = [];
for (let j = 0; j < 5625; j++) {
a.push(f(75));
}
return performance.now() - now;
}
function objectSpread(m: any, n:any) {
return {...m, ...n};
}
function f(i:number) {
const m:Record<number,number> = {}, n:Record<number,number> = {};
for (let k = 0; k < i; k++) {
m[Math.random()] = 0;
n[Math.random()] = 0;
}
return objectSpread(m, n);
}
We do get better performance with the downleveling than with the native spread.
Thanks for bringing this up, we're keeping an eye on the Chromium issue. There is a complex trade off since:
With random input object properties, spread is still 2x slower than assign.
It's hard to say that native spread will be a net perf improvement for all Angular apps. We'll keep watching and see if/when it's appropriate to switch to native.