Description
🐞 bug report
Affected Package
The issue is caused by package @angular/forms
Is this a regression?
Regression from AngularJS.
Description
I noticed that there was a noticeable delay when populating a select dropdown with several hundred+ items using an ngValue binding, which does not occur with other frameworks (I also tested AngularJS and Svelte). Digging into the Angular code it turns out that the _compareWith
function in select_control_value_accessor.ts is being called an absurdly high number of times.
I expected that this function would just be called no more than once for each item in the dropdown (i.e. loop through the options until a match is found). However, it is actually called exponentially more. E.g. for a dropdown with 1000 items and the 500th item bound to the ngModel, the function is called 501,001 times. If there are 3000 items in the dropdown and the 1500th item is selected, the _compareWith
function is called 1,002,501 times. It gets even worse if an option nearer the end of the list is selected.
🔬 Minimal Reproduction
https://stackblitz.com/edit/angular-select-performance?file=src%2Fapp%2Fapp.component.ts
Note that I added a custom compareWith
method in this example to log how many times it is called, but the performance is just as bad with the default internal comparison method.
I think the problem stems from Angular's SelectControlValueAccessor.writeValue()
method being called over and over for each individual option element that is rendered, rather than once after all the options are rendered.
🌍 Your Environment
Angular Version: 11.2.6
Anything else relevant?
This is especially problematic for our users with slower mobile devices.