Ngx-infinite-scroll: Takes a long time for onScroll to fire

Created on 28 Oct 2017  路  28Comments  路  Source: orizens/ngx-infinite-scroll

I have

<div class="search-results" 
    infiniteScroll 
    [infiniteScrollDistance]="2"
    [infiniteScrollThrottle]="500" 
    (scrolled)="onScroll()">
</div>

When I scroll to the bottom, it somtimes takes 4 seconds for onScroll to fire.

I've tried all kinds of values for infiniteScrollDistance. With a high value, it works initially, but after scrolling for a while, the problem is back.

help wanted to-verify investigating needs more INFO

Most helpful comment

I experienced this issue also in Chrome (OS X), but not in other browsers. Happens still with new 0.8.1. It seems that the problematic part is the sampleTime() as adrienverge found out above. I think the root cause might be this: https://bugs.chromium.org/p/chromium/issues/detail?id=661155

sampleTime() uses timeout and while scrolling - especially rapidly with track pad - the events won't arrive. After the scrolling is stopped, it takes couple of seconds and everything is working again.

I wonder if the semantics of the scroll throttle option could be changed a bit, so that 0 would leave the sampleTime() part out totally?

All 28 comments

please share a plunkr that reproduce it.

I experience this as well. But this does not have to do with the firing of scrolled. If you look at the network tab (assuming your onScroll makes an HTTP request), you will see that your onScroll is always called because the HTTP request is made when it should be, it's just that the request itself takes a few seconds to complete. I have no idea why this happens, I had a question on SO about it on a few months back with my own custom infinite scroll directive. Apparently this project has the same bug >.<

It's weird because the lengthy request only happens because it was triggered by this directive, and will never take that long if you do the HTTP call another way, for instance with a button click.

this infinite scroll is an extract from http://echoesplayer.com - where it works pretty well.

I experience the same problem as @ghost (the original author): whatever infiniteScrollThrottle or infiniteScrollDistance values, the callback function is called after approximately 2 seconds.

(@lansana I think you don't have the exact same problem.)

Clue 1: When using [scrollWindow]="false" and height: 20rem; overflow: scroll;, the problem disappears (but this is not a satisfying solution).

Clue 2: Completely removing the throttle in code removes the problem:

--- node_modules/ngx-infinite-scroll/modules/ngx-infinite-scroll.es5.js
+++ node_modules/ngx-infinite-scroll/modules/ngx-infinite-scroll.es5.js
@@ -311,7 +311,9 @@
  */
 function attachScrollEvent(options) {
     return Observable.fromEvent(options.container, 'scroll')
-        .sampleTime(options.throttleDuration)
+        .do(event => console.warn('received event: ' + event))
         .filter(options.filterBefore)
         .mergeMap(function (ev) { return Observable.of(options.mergeMap(ev)); })
         .subscribe(options.scrollHandler);

Clue 3: I tried replacing sampleTime() by debounceTime() and throttleTime(): it does the same "2 seconds delay effect". Only removing it solves the issue.

I tried reproducing the problem using the demo plunker, but couldn't (I even changed versions to use latest software, i.e. Angular 5.0.3, rxjs 5.2.2 and Typescript 2.4.2).

without a demo for this bug - it's hard to pinpoint the cause.
did you try reducing the throttle to 20-50?

Hi @orizens, thanks for following this up.

without a demo for this bug - it's hard to pinpoint the cause.

I agree, and I'm sad I couldn't reproduce this in a plunker although I spent 30 min trying. I guess it's related to other dependencies in my project. I tried various versions of Angular, RxJS, Typescript and ngx-infinite-scroll.

did you try reducing the throttle to 20-50?

Of course! I even tried 0. The only thing that works is really removing the call to sampleTime() in the code.

I also noticed that replacing .sampleTime(options.throttleDuration) by any other RxJS function (e.g., .delay(0)) results in the same bug. Only completely removing the call to any RxJS function solves the problem.

it sounds like something in your app its out of zone and enters back after some processing.

Hey Oren,

I'm not sure about that, because console.warn() logs really are delayed of 2 seconds, i.e. it's not only Angular change detection.

node_modules/ngx-infinite-scroll/modules/ngx-infinite-scroll.es5.js:

 function attachScrollEvent(options) {
     return Observable.fromEvent(options.container, 'scroll')
+        .do(event => console.warn('I am displayed instantaneously'))
         .sampleTime(10)
+        .do(event => console.warn('I am displayed after 2 seconds'))
         .filter(options.filterBefore)

Another "funny" thing: the problem only happens with a mouse or trackpad. When using keyboard buttons (page down, end, arrows), all console.warn() logs are displayed instantaneously and the (scrolled)=... callback also.

interesting - we need to find the cause, as sampleTime does work as expected for other use cases.

all - please try latest 0.8.0.

I experienced this issue also in Chrome (OS X), but not in other browsers. Happens still with new 0.8.1. It seems that the problematic part is the sampleTime() as adrienverge found out above. I think the root cause might be this: https://bugs.chromium.org/p/chromium/issues/detail?id=661155

sampleTime() uses timeout and while scrolling - especially rapidly with track pad - the events won't arrive. After the scrolling is stopped, it takes couple of seconds and everything is working again.

I wonder if the semantics of the scroll throttle option could be changed a bit, so that 0 would leave the sampleTime() part out totally?

you can tryout zero now.
I'll think of how we can toggle between throttle and sampleTime

Bug still present with versions 0.8.0 and 0.8.1, with or without [infiniteScrollThrottle]="0".

The problem still lies in the call to sampleTime(options.throttle):
https://github.com/orizens/ngx-infinite-scroll/blob/7880627955765d8d50575f75e5a9a79b4bb8bb85/src/services/scroll-register.ts#L64

@orizens maybe if options.throttle 0 or null return without sampleTime?
I tried this solve
function attachScrollEvent(options) { var obs = Observable.fromEvent(options.container, 'scroll'); return options.throttle ? obs.sampleTime(options.throttle) : obs; },
it`s helped me.
I use version 0.8.2

@orizens I have to admit I'm not sure why you closed this issue.

This is a real bug that directly impacts the functionality of your library in the most used browser by market share by far.

I just thought your library didn't work properly as I always develop in chrome then checked out the infinite scrolling of my app in safari and was surprised to see it works fine.

I understand this is open source and other people can contribute solutions but at least keep the issue open until fixed!

@jcroll does zero helps?
It seems like this is a bug in chrome.
I'll reopen to allow pr from community

@orizens yes, zero not helps.

Thanks @orizens. No the zero doesn't help, I believe some of the devs in this thread are closing in on the issue tho.

Experience same issue. Same HTTP requests that can 30ms, take 2.3 seconds :(
And this code doesn't helped
const obs = Observable.fromEvent(options.container, 'scroll'); return options.throttle ? obs.throttleTime(options.throttle) : obs;
P.S Chrome (OS X)

@orizens Hi guys, I've faced the same trouble :( Any estimation when it can be fixed? Thanks!

I have opened https://github.com/orizens/ngx-infinite-scroll/pull/235, it solves the problem for me when using [infiniteScrollThrottle]="0".

Same here. Using [infiniteScrollThrottle]="0" as a workaround "solves" the issue.

@adrienverge thanks - looking at your pr.
@zaikin-andrew - i'm inspecting possible solutions

@orizens thanks!

version 0.8.3 released

Issue still exists with last version of Chrome and even with [infiniteScrollThrottle]="0".

Thanks to this post, it seems I solved the issue.

I added a mousewheel listener on infinite scroll directive :

@HostListener('mousewheel') onMouseWheel() { }

No more slow http request.

I have been struggling a lot with this, without knowing it was related to this library or this issue. I am using Angular Elements, and it was behaving properly during the development. When I finished the component, bundled, and started using in my website, it would not scroll.

I thought it was something about angular, about angular elements, about me missing something about how events work with elements, etc. Two days later, after testing with my own scroll listener and realizing mine would work, I commented out the lines ofsampleTime if, and it finally started working.

I also did an experiment of replacing the sampleTime, with throttleTime and it also works. Was this option already considered?

I also think this issue should not have been closed, or at least the default value for infiniteScrollThrottle should have been modified to 0. It didn't occur to me to add an optional property and set it to 0 would solve the problem. I doubt anyone would try that.

Was this page helpful?
0 / 5 - 0 ratings