Hello everyone,
I’ve been struggling for a (very long) while on performance issues on my app, that concern list switching with segment buttons.
I’m using virtual scroll to improve perfs, because a ngFor loop was insanely slow with only 200 elements.
In my template:
<ng-container *ngIf="currentList$ | async as currentList" class="full-height">
<card-game-list
[gameList]="currentList"
[isWishList]="currentList.settings.url === 'wishlist'"
></card-game-list>
</ng-container>
</ion-content>
<ion-footer >
<ion-toolbar>
<!-- LIST BUTTONS-->
<ion-segment *ngIf="boardGames.gameLists$ | async as lists" (ionChange)="selectList($event)">
<ion-segment-button class="menuSegmentButton menuSegment{{list.settings.name}}"
*ngFor="let list of lists; let i = index"
[value]="list.settings.name"
[class.segment-button-checked]="(currentList$ | async)?.settings.name === list.settings.name"
>
<ion-icon [name]="list.settings.iconUrl" class="ion-no-margin"></ion-icon>
<ion-label class="small-margin-bottom">
{{ list.settings.name }}
<ion-badge>
{{ list.filteredGamesCount$ | async }}
</ion-badge>
</ion-label>
</ion-segment-button>
</ion-segment>
</ion-toolbar>
</ion-footer>
Which gives this:
The custom component ‘card-game-list’ is basically a virtual scroll with ion-cards.
The problems I have:
It take about half a second to swicth from a list to an other, when I click on a segment button, there’s a short lag, then everything happens at the same time : the other list is displayed and the ripple effect occurs but in a laggy way.
The profiling shows this:
The Animation Frame Fired Takes allthe processing time (0.5s),I don’t know iff that’s supposed to work that way.
What I’ve tryied:
- Change Detection strategy to OnPush -> Improved the problem but still here
- All virtual scroll I could fing on npm (+ cdk) -> they all had their own unacceptable issues :’(
- Having much simplercomponent for the virtual scroll -> didn’t changeanything
To go deeper:
What I think is it all have to do with the way I switch lists,that is to say
public selectList($event) {
const selectedList = $event.target.value;
console.log(selectedList);
this.boardGames.gameLists$.subscribe(lists => {
this.listSubject.next(
lists.find(list => list.settings.name === selectedList)
);
});
}
I’m using RxJs observable to next the new list to the component,and I have the feeling
that’s not the best option.
So questions are:
1 - Does it seems legit to use observable like this to switch lists ?
2 - Is there a way to call first the ripple animation (immediately) and then do the switching work?
Thanks for your help
Ionic infos
Ionic:
Ionic CLI : 5.4.16 (C:\Users\Piwi\AppData\Roaming\npm\node_modules\ionic)
Ionic Framework : @ionic/angular 5.0.7
@angular-devkit/build-angular : 0.803.26
@angular-devkit/schematics : 8.3.26
@angular/cli : 8.3.26
@ionic/angular-toolkit : 2.2.0
Cordova:
Cordova CLI : 9.0.0
Cordova Platforms : not available
Cordova Plugins : not available
Utility:
cordova-res : not installed
native-run : not installed
System:
NodeJS : v12.16.1 (C:\DEV\tools\nodejs\node.exe)
npm : 6.13.4
OS : Windows 10