Speeding Up Angular Material Autocomplete or Alternatives

Viewed 3553

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)?

3 Answers

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.

Filtering after checking the value length made this work as PeekYou mentioned

Related