Issue
We have an ionic angular app which is basically a contact management app. The app becomes horribly slow as the contacts increases in the app. The taps, scrolls everything becomes slow.
The app uses offline storage and populate the data into a array which is used to render the list of cards. So, network is not an issue.
I have around 1200 contacts where this issues is happening. Please advise how can i debug issues.
The code of the list page looks like below:
<ng-container *ngIf="core.syncedCards != undefined && core.syncedCards.length > 0">
<ng-container *ngFor="let card of core.syncedCards">
<app-contact-card [card]="card"></app-contact-card>
</ng-container>
</ng-container>
The component code is:
<ion-card>
<ion-item lines="none">
<ion-label (click)="viewCard(card)">{{card.firstName}} {{card.lastName}}</ion-label>
<ion-button fill="clear" slot="end" (click)="toggleFavorite(card)">
<ion-icon slot="icon-only" color="warning" name="star"></ion-icon>
</ion-button>
</ion-item>
<ion-card-subtitle>{{getJobDept()}}</ion-card-subtitle>
<ion-card-content>
<ion-item (click)="viewCard(card)">
<ion-thumbnail slot="start" class="profile-pic">
<img src="assets/images/noPerson.jpg">
</ion-thumbnail>
<ion-label class="ion-text-wrap">
<ion-row><ion-col class="ion-no-padding">{{card.company}}</ion-col></ion-row>
<ion-row><ion-col class="ion-no-padding">{{card.city}}, {{card.state}}</ion-col></ion-row>
<ion-row *ngIf="card.tags !== undefined && card.tags.length > 0">
<ion-col size="auto" *ngFor="let tag of card.tags">
<ion-chip [color]="core.getTagColor(tag)">
{{tag}}
</ion-chip>
</ion-col>
</ion-row>
</ion-label>
</ion-item>
<ion-row class="ion-padding" style="padding-bottom:0px" *ngIf="refreshActions() === true">
<ng-container *ngFor="let action of cardActions;let i = index">
<ion-col size="2" *ngIf="i < 3">
<ion-icon [name]="getLogoName(action.type)" [color]="getLogoColor(action.type)" size="large" (click)="doCardAction(action.type, card)"></ion-icon>
</ion-col>
</ng-container>
<ion-col size="auto" *ngIf="cardActions.length > 3">
<ion-icon name="chevron-down-outline" color="secondary" size="large" (click)="expandActions()"></ion-icon>
</ion-col>
<ion-col class="ion-text-right" *ngIf="card.status == globalVariables.SYNC_FAILED">CRM Sync failed</ion-col>
<ion-col class="ion-text-right ion-no-padding">
<ion-icon name="ellipsis-vertical" size="large" (click)="showCardActions($event, card)" ></ion-icon>
</ion-col>
</ion-row>
<ng-container *ngIf="showMoreActions === true">
<ion-row class="ion-padding" style="padding-bottom:0px">
<ng-container *ngFor="let action of cardActions;let i = index">
<ion-col size="2" *ngIf="i > 2">
<ion-icon [name]="getLogoName(action.type)" [color]="getLogoColor(action.type)" size="large" (click)="doCardAction(action.type, card)"></ion-icon>
</ion-col>
</ng-container>
</ion-row>
</ng-container>
</ion-card-content>
</ion-card>
The code to populate syncedCards is like below:
const sCards = await this.storage.get("syncedCards")
this.core.syncedCards = []
console.log("offline synced cards are:", this.core.syncedCards)
for(const card of sCards){
this.core.syncedCards.push(this.core.copyContactDataFromJson(card))
}
copyContactDataFromJson(cardQ: any) {
var card = new Card(cardQ._tempContactId, cardQ._frontImageUrl, cardQ._backImageUrl,
cardQ._status, cardQ._date, cardQ._userId, cardQ._message, cardQ._objectType)
card.firstName = cardQ._firstName
card.lastName = cardQ._lastName
card.jobTitle = cardQ._jobTitle
card.company = cardQ._company
card.email = cardQ._email
card.mobile = cardQ._mobile
card.workPhone = cardQ._workPhone
card.website = cardQ._website
card.street = cardQ._street
card.city = cardQ._city
card.state = cardQ._state
card.country = cardQ._country
card.postalCode = cardQ._postalCode
card.favoriteContact = cardQ._favoriteContact
card.profilePic = cardQ._profilePic
card.dept = cardQ._dept
card.fax = cardQ._fax
card.workPhoneExtn = cardQ._workPhoneExtn
card.buddyCode = cardQ._buddyCode
card.buddyCodeLower = card.buddyCode.toLowerCase()
card.mobileCountryCode = cardQ._mobileCountryCode
card.mobileAreaCode = cardQ._mobileAreaCode
card.mobileNumber = cardQ._mobileNumber
card.mobileRawNumber = cardQ._mobileRawNumber
card.workPhoneCountryCode = cardQ._workPhoneCountryCode
card.workPhoneAreaCode = cardQ._workPhoneAreaCode
card.workPhoneNumber = cardQ._workPhoneNumber
card.workRawNumber = ''
card.workRawNumber = cardQ._workRawNumber
card.favoriteContact = false
card.partyId = -1
card.partyNumber = ''
card.addressNumber = ''
card.accountPartyNumber = cardQ._accountPartyNumber
card.accountPartyId = cardQ._accountPartyId
card.relationshipRecId = cardQ._relationshipRecId
card.note = cardQ._note
card.urlType = cardQ._urlType
card.socialLinks = cardQ._socialLinks
card.requireApproval = false
card.tags = cardQ._tags
card.phones = cardQ._phones
return card
}
Solution
In my opinion, the problem is that you have so many items loaded. Even if your phone screen doesn't allow visualizing every of them, they slow down your app.
You have two solutions:
- If the contacts are not going to keep increasing: I recommend you to use
cdk-virtual-scroll-viewport
(documentation) to lazy load the elements. It only renders the items that fit on-screen.
Example:
<cdk-virtual-scroll-viewport [itemSize]="userItemHeight" minBufferPx="400" maxBufferPx="800" #usersVirtualScroll>
<ion-list>
<app-favourites-reorder [favouriteUsers]="allUsersList.favourites" (movedList)="saveReorderFavourites($event)" *ngIf="reorderFavouriteUsers"></app-favourites-reorder>
<div *cdkVirtualFor="let user of users">
<app-user-item [user]="user">
</app-user-item>
</div>
</ion-list>
</cdk-virtual-scroll-viewport>
- If the contacts are going to keep increasing: You can use
ion-infinite-scroll
(documentation) to get contacts from database little by little instead of everything at once. Now you have 1,200 contacts, but think about when you have 1,000,000.
Example:
<ion-content>
<ion-list>
<ion-item *ngFor="let item of items; let index">
<ion-avatar slot="start">
<img [src]="'https://picsum.photos/80/80?random=' + index" alt="avatar" />
</ion-avatar>
<ion-label>{{ item }}</ion-label>
</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="onIonInfinite($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-content>
Answered By - Miguel
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.