Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 *ngFor performance issue with select/option

I'm using *ngFor to populate options of <select></select>. My issue is that I can have 1000 array values for 1 of my 6 <select>. Performance is suffering. I know it's because of changeDetection or One-way Binding. Is there a way to better implement *ngFor for <option>. I don't actually need change detection or one-way binding.

My Code

<select [formControl]="requestForm.controls['SellCommodityId']">
   <option [value]="" disabled selected>COMMODITY/GRADE</option>
   <option [value]="item.Id" *ngFor="let item of fieldOptions?.Product;">{{item.Value}}</option>                
</select>

UPDATE 12-20-2016

I placed the select into it's one Component like this:

import { Component, ChangeDetectionStrategy,Input } from '@angular/core';
/**
 * <ihda-select [list]="list" [control]="control" [titleOption]="title"></ihda-select>
 */
@Component({
  selector:'ihda-select',
  changeDetection:ChangeDetectionStrategy.OnPush,
  template:`
    <select [formControl]="control" class="form-control">
       <option [value]="" disabled selected>{{titleOption}}</option>
       <option [value]="item.Id" *ngFor="let item of list">{{item.Value}}</option>                
     </select>
  `,
  styleUrls: ['../app.component.css']
})
export class IHDASelect{
    @Input() list: any[];
    @Input() control: any;
    @Input() titleOption: string;
}

Performance issue persisted.

It seems like it wasn't the changeDetection, because i tried removing the [formControl] attribute from the <select> and then there was no longer a performance issue. It seems that using the [formControl] attribute here to track it for the form group causes the performance issue. Is there information about this? or how I may fix it?

UPDATE 12-21-2016

Performance Issue shown in the plunker here:

https://plnkr.co/edit/2jNKFotBRIIytcmLto7y?p=preview

If you click the Options Route it will take a long time to load the options. If you remove the form code the route doesn't take a long time to load.

like image 345
Abdullah Rasheed Avatar asked Dec 16 '16 01:12

Abdullah Rasheed


1 Answers

When the Options route is selected all <options> for all <select> are rendered in one go before the application responds again.

To avoid that the rendering of the <options> could be delayed so that they are only rendered on demand

<select [formControl]="control" class="form-control" (focus)="hasFocus = true">
   <option [value]="" disabled selected></option>
   <ng-container *ngIf="hasFocus">
     <option [value]="item.id" *ngFor="let item of list">{{item.value}}</option>                
   </ng-container>
</select>

https://plnkr.co/edit/KRgYHktFXHyPugS3nPQk?p=preview

The strategy can be further optimized so that hasFocus is set to true delayed by a timer after the component is already shown for one <select> at a time, so that while the browser is idle it already renders the <option>s.

like image 71
Günter Zöchbauer Avatar answered Oct 24 '22 01:10

Günter Zöchbauer