Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speeding Up Angular Material Autocomplete or Alternatives

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

like image 204
dandev91 Avatar asked Jul 21 '17 05:07

dandev91


2 Answers

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.

like image 80
dandev91 Avatar answered Oct 16 '22 15:10

dandev91


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.

like image 38
Robouste Avatar answered Oct 16 '22 14:10

Robouste