ngx-virtual-scroller icon indicating copy to clipboard operation
ngx-virtual-scroller copied to clipboard

Scolling is Jittery in iOS

Open jsBiztech opened this issue 6 years ago • 11 comments
trafficstars

I am using this virtual scroll to display data with lazy loading in Ionic 3. It is working fine with browser and android app but in iOS sometimes the scrolling becomes jittery because of some reasons, which I was unable to find. Here are the details:

Ionic:
   Ionic CLI          : 5.2.1
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.1

Cordova:
   Cordova CLI       : 7.1.0
   Cordova Platforms : android 6.3.0
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 4.0.1, (and 21 other plugins)

Utility:
   cordova-res : not installed
   native-run  : not installed

System:
   NodeJS : v10.15.3
   npm    : 6.4.1
   OS     : Linux 4.18

Package Version: 
  angular2-virtual-scroll: ^0.4.9,

Template Structure:

<ion-content no-bounce>
    <div [ngClass]="isPlatformBrowser == true ? 'page-wrapper':'mobile-wrapper'">
        <div class="library-wrapper" [class.no-data]="searchRelateData?.length == 0"
                [ngClass]="isPlatformBrowser == true ? 'lg-wrapper-main':'sm-wrapper-main'">
            <ng-template [ngIf]="!listprogress" [ngIfElse]="loadingTemplate">
                <ng-container>
                    <ion-content no-padding no-bounce *ngIf="!isPlatformBrowser">
                        <div class="scroll">
                            <virtual-scroll id="library-vs" [class.no-data]='!filteredListing?.length' (scroll)="onListChange($event)" [items]="filteredListing"
                                (update)="viewPortItems = $event" [childHeight]="6" [bufferAmount]="limit">
                                <div class="item text-elipsis" *ngFor="let item of filteredListing | customFilterPipe">
                                    <custom-component></custom-component>
                                </div>
                                <div *ngIf="listLoading" class="loader">LOADING...</div>
                            </virtual-scroll>
                        </div>
                    </ion-content>
                </ng-container>
            </ng-template>
        </div>
    </div>
</ion-content>

jsBiztech avatar Jul 06 '19 06:07 jsBiztech

I was having the same issue. I found that using <li> works best, instead of using div or <ion-item>.

luqmaants avatar Jul 08 '19 15:07 luqmaants

Thanks for the reply @luqmaants .Did you used <li> inside <virtual-scroll>. Also I am facing this issue in iOS only, Do you think this will resolve the issue?

jsBiztech avatar Jul 09 '19 04:07 jsBiztech

Same issue here. @luqmaants and @nagdevbharat did this help you? It doesn't seem to make a difference for me.

lincolnthree avatar Aug 17 '19 14:08 lincolnthree

@lincolnthree , the issue still persists. Have you found any solution for this?

jsBiztech avatar Dec 19 '19 09:12 jsBiztech

Negative. No ideas here. I'm not very practiced with animations/etc. I try to avoid that level of UI unless absolutely necessary. I tried replacing with ion-virtual-scroll, but that component has even more issues. Just suffering through the jitter at the moment.

lincolnthree avatar Dec 19 '19 14:12 lincolnthree

I was having the same issue, solved it by installing WKWebView. ionic cordova plugin add cordova-plugin-ionic-webview --save

ambu50 avatar Jan 15 '20 11:01 ambu50

@ambu50 , I have webview installed: ionic-native/ionic-webview: ^5.6.1 and the issue still persists

jsBiztech avatar Jan 16 '20 05:01 jsBiztech

@nagdevbharat @lincolnthree I Just implemented a solution for my use case, here's what it looks like:

<virtual-scroller #scroll [items]="arrayOfItems"" [executeRefreshOutsideAngularZone]="executeRefreshOutsideAngular" (vsStart)="vsStartUpdate($event)"> <div > CONTENT</div> </virtual-scroller>

And in the typescript file:

`public executeRefreshOutsideAngular: boolean = false;

public vsStartUpdate(event: IPageInfo) { if(!this.arrayOfItems) return; this.toggleChangeDetectionOfVirtualScroller(event); }

private toggleChangeDetectionOfVirtualScroller(event: IPageInfo){ if(event.endIndex >= this.arrayOfItems.length-1){ // we are at the bottom of the list // executeRefreshOutsideAngularZone IF the user is not scrolling up // if (event.scrollStartPosition <= event.scrollEndPosition) // means we are scrolling upwards, and wa want to set the boolean to false, otherwise true // this.executeRefreshOutsideAngular = event.scrollStartPosition <= event.scrollEndPosition; } else { this.executeRefreshOutsideAngular = false; this.forceDetectChanges(); } }

public forceDetectChanges() { this.changeDetectorRef.detectChanges(); }`

Basically I check if the last item in the viewport is the last item in the list of items. If it is, and if the user is not scrolling back up, i set executeRefreshOutsideAngularZone to true, otherwise false. when setting the executeRefreshOutsideAngularZone back to false, I also force change detection because otherwise it was being a bit buggy

IfreannMedia avatar Jan 17 '20 15:01 IfreannMedia

Hi @IfreannMedia , Sorry for the late reply. I tried the code and it doesn't seem to be working in my project. Can you please provide more details on what happens when change detection is called? Thanks

jsBiztech avatar Jan 27 '20 13:01 jsBiztech

I tried the solution of @IfreannMedia, too. Unfortunately, this didn't solve the issue for me. It looks as if it makes it even worse 😕

felixble avatar Apr 23 '20 16:04 felixble

Can confirm this. Happens in any browser in IOS

julianpoy avatar Aug 04 '20 05:08 julianpoy