I am using Angular Materials autocomplete to allow a user to search a string of the format: "[ID #] - [Textual Description]". The data is pre-retrieved at the very beginning of the page loading and holds approximately 39,000 strings.
My HTML code is:
<md-input-container>
<input mdInput placeholder="TSN Search" [mdAutocomplete]="auto" [formControl]="TSN_Ctrl">
</md-input-container>
<md-autocomplete #auto="mdAutocomplete">
<md-option *ngFor="let tsn of filtered_TSNs | async" [value]="tsn">
{{ tsn }}
</md-option>
</md-autocomplete>
And my typescript code is:
TSN_Ctrl: FormControl = new FormControl();
filtered_TSNs: any;
constructor(){
this.filtered_TSNs = this.TSN_Ctrl.valueChanges
.startWith(null)
.map(val => val ? this.filter_TSNs(val) : this.dataService.tsnTitles.slice());
}
private filter_TSNs(val: string) {
return this.dataService.tsnTitles.filter(option => new RegExp(`^${val}`, 'gi').test(option));
}
I am essentially using the standard code from the Angular Materials example, with a slight adaptation.
The autocomplete function is incredibly slow and essentially non-responsive. I understand there are a lot of options (39k strings) but it is pre-retrieved and locally stored.
Is there something I can do to speed this up or are there simply too many strings in the list? If I modify the filter method and strings to only contain the ID field, could that speed up the process? Do I need to use an entirely different library (i.e. if Angular Materials Autocomplete is known to be slow)?
Will Howell's advice of "The true culprit is probably the autocomplete/angular trying to render 39k option components (!) You may want to return a subset in filter_TSNs (like the first 50 options)" was the issue and should be the accepted answer. By limiting the search function to only display autocompleted results until the 4th character, the autocomplete became instantaneous.
An other solution would be to use the Virtual Scroll from the Angular CDK.
<mat-autocomplete #auto="matAutocomplete">
<cdk-virtual-scroll-viewport itemSize="48" style="height: 256px">
<mat-option *cdkVirtualFor="let tsn of filtered_TSNs | async" [value]="tsn">
{{ tsn }}
</mat-option>
</cdk-virtual-scroll-viewport>
</mat-autocomplete>
The height: 256px
is important, otherwhise you will not see it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With