Search code examples
angularperformanceionic-frameworkfirebase-realtime-databaseangularfire2

ionic 4 list rendering takes a very long time


I am using ionic 4 and my code pulls data from firebase. there are 40 objects that comes from the request. I am pushing them into a array and then using ion-list to render it.

Rending these 40 objects takes 8-10 sec. Which i believe is a huge time. Below is the code doing this and html

<ion-content>
  <ion-searchbar style="padding-bottom:0px" placeholder="{{ 'CONTACT_SEARCH_PLACEHOLDER' | translate }}"  (ionChange)="doSearch()" [(ngModel)]="searchTerm" (ionClear)="searchReset()"></ion-searchbar>

  <ion-list>
    <ion-list-header>
        <ion-label>{{ 'FAVORITE_CONTACTS' | translate }}</ion-label>
    </ion-list-header>

    <ng-container *ngFor="let card of core.syncedCards">
      <app-contact-card *ngIf="card.favoriteContact == false" [card]="card"></app-contact-card>
    </ng-container>  
   </ion-list>

</ion-content>

Contact-card component html is

<ion-card  style="margin-top:5px">
  <ion-card-header [ngClass]="card.partyNumber == 'demo' ? 'demoCard' : 'realCard'">
    <ion-card-title>
        {{card.firstName}} {{card.lastName}}    
        <ion-icon name="more" mode="md" color="primary"  size="large"  style="float:right" (click)="showCardActions($event, card)"></ion-icon>
        <ion-icon *ngIf="card.partyNumber == 'demo'"  size="large"  style="float:right" color="danger" name="trash" (click)="deleteDemoCard(card.tempContactId)"></ion-icon>
        <ion-icon style="float:right" size="large" *ngIf="card.favoriteContact == true" color="warning" name="star" (click)="toggleFavorite(card)"></ion-icon>
        <ion-icon style="float:right" size="large" *ngIf="card.favoriteContact == false" color="warning" name="star-outline" (click)="toggleFavorite(card)"></ion-icon>
  </ion-card-title>
  <ion-card-subtitle>{{card.jobTitle}}<span *ngIf="card.dept != undefined && card.dept != ''">,&nbsp;{{card.dept}}</span></ion-card-subtitle>
</ion-card-header>
  <ion-card-content style="padding:0px">
    <ion-item (click)="viewCard(card)">
        <ion-thumbnail slot="start" class="profile-pic">
          <img *ngIf="card.profilePic  == undefined || card.profilePic == ''" src="assets/images/noPerson.jpg">
          <img *ngIf="card.profilePic  != undefined && card.profilePic != ''" [src]="card.profilePic">
        </ion-thumbnail>
        <ion-label class="ion-text-wrap">
           <ion-row><ion-col  class="ion-no-padding">{{card.company}}</ion-col></ion-row>
           <ion-row *ngIf="card.city != undefined && card.city != '' && card.state != undefined && card.state != ''"><ion-col  class="ion-no-padding">{{card.city}}, {{card.state}}</ion-col></ion-row>
           <ion-row *ngIf="(card.city == undefined || card.city == '') && card.state != undefined && card.state != ''"><ion-col  class="ion-no-padding">{{card.state}}</ion-col></ion-row> 
           <ion-row *ngIf="card.city != undefined && card.city != '' && (card.state == undefined || card.state == '')"><ion-col  class="ion-no-padding">{{card.city}}</ion-col></ion-row> 
       </ion-label>
      </ion-item>
      <ion-row class="ion-padding" style="padding-bottom:0px"> <ion-col size="auto" *ngIf="card.mobile != undefined && card.mobile != ''"> 
        <ion-icon name="phone-portrait" color="primary" size="large" (click)="callPhone(card.mobileCountryCode, card.mobile)"></ion-icon>
        </ion-col>
        <ion-col size="auto"  *ngIf="card.workPhone != undefined && card.workPhone != ''"> 
          <ion-icon name="call" color="primary" size="large" (click)="callPhone(card.workPhoneCountryCode, card.workPhone)"></ion-icon>
        </ion-col>
        <ion-col size="auto" *ngIf="card.email != undefined && card.email != ''">
            <ion-icon name="mail" color="primary"  size="large" (click)="sendMail(card.email)"></ion-icon>
        </ion-col>
        <ion-col size="auto" *ngIf="card.website != undefined && card.website != ''">
          <ion-icon name="globe" color="secondary"  size="large" (click)="openSite(card.website)"></ion-icon>
      </ion-col>
      <ion-col class="ion-text-right" *ngIf="card.status == globalVariables.SYNC_FAILED" style="font-size: small">CRM Sync failed</ion-col>
    </ion-row>
</ion-card-content>
</ion-card>

the code filling up the syncedCards is

this.syncedCards = []
const res:any = await this.dataSvc.getPendingCards(this.getUserKey())
for(let cardQ of res) {
  if(cardQ._status == GlobalVariables.QUEUED || cardQ._status ==  GlobalVariables.REJECTED)
    continue

    var card = this.copyContactDataFromJson(cardQ)
    this.syncedCards.push(card)
}

UPDATE 12/23: i am now sure it is not a network issue. The data is available in the syncedCards array in less than a sec. the entire 8-10 sec are spend in just rendering.


Solution

  • So, I am not going to close this but here is one thing that made huge difference and i was kind of ignoring it all my life.

    while creating the build i was doing it without --prod flag and just using the --prod flag has got the UI rendering time from 25+ sec to 3-5 sec.

    It is still high but at least manageable and acceptable as app is now not useless anymore just waiting to render.