I have an issue with the ion-slides component. I'm calling a method within my ion-slide
but noticed that this method is called RIDICULOUSLY OFTEN and i'm not sure why. It also slows everything down significantly.
Initially the method is called 900 times (even though i'm only showing 100 slides) and the slightest drag of the slides again triggers 900 method calls, so by just swiping from the first to the second slide the method has been triggered 5000+ times, depending on how slowly I swipe.
Any ideas why? I'm using Ionic 4.4, Angular 5.0.3 and Ionic-Angular 3.9.2.
Template
<ion-content>
<ion-slides>
<ion-slide *ngFor="let slide of slides">
<div>
{{slide}} - {{myMethod()}}
</div>
</ion-slide>
</ion-slides>
</ion-content>
Component
@Component({
selector: 'page-my',
templateUrl: 'my-page.html'
})
export class MyPage implements OnInit {
slides: number[] = [];
methodCounter: number = 0;
ngOnInit() {
let numberOfSlides = 100;
for (var i = 0; i < numberOfSlides; i++) {
this.slides[i] = i;
}
}
public myMethod(): string {
console.log('myMethod called ' + this.methodCounter++);
return 'foo';
}
}
I would suggest to change the ChangeDetectionStrategy on your component to "OnPush": (see more information here: angular change detection explained)
Your component would look like this afterwards:
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'page-my',
templateUrl: 'my-page.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyPage implements OnInit {
slides: number[] = [];
methodCounter: number = 0;
ngOnInit() {
let numberOfSlides = 100;
for (var i = 0; i < numberOfSlides; i++) {
this.slides[i] = i;
}
}
public slideChanged(): void {
console.log('slide changed');
this.cd.markForCheck();
}
public myMethod(): string {
console.log('myMethod called ' + this.methodCounter++);
return 'foo';
}
}
Your html template would look like this:
<ion-slides (ionSlideDidChange)="slideChanged()">
<ion-slide *ngFor="let slide of slides">
<div>
{{slide}} - {{myMethod()}}
</div>
</ion-slide>
</ion-slides>
</ion-content>
Explanation:
With the change of the ChangeDetectionStrategy you basically tell angular that you know when it should re-render the component and if this event occurs you tell it by calling markForCheck()
. So everytime the slides get changed, the slideChanged()
method is called and we explicitly tell angular it should re-render this component. When the component gets re-rendered, the method myMethod()
should be executed again and the updated content displayed. This way you have a component that is much more performant and the method myMethod()
is only called upon initialization or when you explicitly tell so.