You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug: infinite scroll event does not fire if quickly scrolled #18071
If you initially load not enough items to fill the page and to enable scrolling, ionInfinite will never fire. You have to resize the browser window.
If you scroll down quickly, ionInfinite does not always fire, especially when you load only few additional items and/or the threshold is set to a high value. You have to scroll up and back down.
This is an issue because:
You might want to load as few items as possible, especially if the load time is high or because of bandwidth/costs.
You never now how many items are enough to fill the page, because of screen size, font size, etc..
Expected behavior:
I expect ionInfinite to fire when more items can be shown on the page.
Happy to look into this one, we also ran into this and for now just used a very large default page size, but it would be nice if the component invoked the infinite method until it fills the viewable area. The important part is to make sure it stops requesting if the list doesn’t grow (there truly are no more items)
Reacted by Michael Callaghan, Sebastián Ferreras and Manuel Becker
Just encountered this with v6.1.3 with ionic-vue. While in dev mode with a browser one can shrink the browser to create a scrollbar to trigger the scroller but this trick will not work when the app is deployed (only tested android). Anyone have a workaround to trigger the scroll for a deployed app if only a few items are on the page?
@Chris1234567899 thanks for the workaround but unfortunately it won't work in my use case as each scroll action is associated with a chunk of time which may or may not have any items for that time range. Moreover I do not know the total number of items. If a scroll bar is present I have the component working to pull the next chunk of data for the next time range however if no scroll bar exists or the scrollbar that exists doesn't pass the threshold check the component will do nothing. One thought I had of was using the ion-refresher component for my use case however it doesn't support an option to use it at the bottom of the page. I may end up just adding a fab to trigger loading the next chunk of data instead of using the infinite scroll component or if time permits work with the team providing the API I'm using to get data to add a method to page the data by number of items instead.
Glad to see that not only I am having issues with this extremely frustrating issue. For me, it's happening when I am scrolling a bit faster and the API is not responding quickly enough. With very fast scrolling I could even reproduce the issue in the Ionic documentation.
It's always loading 2 times and then it stops working. I also posted this issue in the Ionic forums but didn't get any response. The issue occurs when you reach the ion-infinite-scroll-content before complete() was called. What can solve it is to simply call complete() immediately before loading the data but then you have to solve the issue that the API could answer with page 3 before page 2.
An additional hint after testing it quite a lot on different devices: This issue seems to only affect Android devices and browsers which could be the case because Apple has this rubberband effect that seems to help since scrolling is not stopping at a very strict position. But that's just an assumption.
I know this is fairly old so apologies for bumping, but this is still an issue when testing with @ionic/react v6.1.9, are there any plans for Ionic to support better behaviour when there's an infinite list with not enough elements to initiate scrolling? I agree with the OP's expected behaviour, I'd also expect ionInfinite to fire more than once if there are more items available
Thanks for the clarification. I'm not sure how Ionic would account for this in a general sense (i.e. for many use cases) since we don't know when your inner content is loaded. This still seems like an implementation issue. However, I can think of a few options to avoid this:
Load more items than you need
As you noted above above, this isn't always feasible especially with devices that have large screens such as tablets. You would potentially be loading 50+ items at once which can have negative performance implications.
Recursively paginate data
This is a slightly more sophisticated version of option 1 where you load in increments of n until your content can scroll. You could implement something like this:
a. Load n data points.
b. Check if your content can scroll. (check If the height of the list > height of the content visible area)
c. If your page can scroll then you are done.
d. If the page cannot scroll then load n more data points and go back to step a and repeat.
Add a "Load More" button at the bottom of the page
You could show this button so users can manually fetch more data. Once data has been fetched or when the infinite scroll event fires then you can hide the button.
@liamdebeasi Thank you, I definitely got your point. I still think (if possible) that the component should check if it reached the "I should load the next page"-state but currently isn't because there is no actual scroll event possible or happening. Adding a very subtle "load more" button is a good idea for sure and I will probably add it now as a workaround but I am sure that others using the component are not even aware of these "restrictions" and are therefore delivering broken endless scroll pages. On iOS the first issue is a bit less affected because you have the bounce scroll and if the user pushes a bit more the event suddenly fires sometimes but that feels anything else than smooth.
So basically checking more often if the scroll area is visible and firing a scroll event based on that manually is probably the only viable option I see, isn't it?
Thank you anyway for your thoughts and efforts, I highly appreciate them and I hope you can understand my perspective that I would love to provide a smooth experience and this would help a lot if it was solved somehow.
Edit: This results in a lot more effort than I thought because if you offer the load more button or want to check all this by yourself, you also need to implement a parallel prevention that the infinite load gets fired while you are loading content yourself without it. I was searching if there is some function to at least fire the event so that I don't need to do that but couldn't find anything. So the only way is to set the infinite load to disabled as soon as I do something and enable it again afterward, right?
Sorry for so much content but when I google for the issue I see lots of people having the same issue, trying to solve it somehow for over 5 years (which is when I recognized the issue the first time) and all of these approaches might look okay but they actually aren't for various reasons.
changed the title [-]bug: Infinite scroll not always working when few items are loaded[/-][+]bug: infinite scroll event does not fire if quickly scrolled[/+]on Oct 9, 2023
Thank you, I definitely got your point. I still think (if possible) that the component should check if it reached the "I should load the next page"-state but currently isn't because there is no actual scroll event possible or happening.
Yeah that's my point: Ionic has no idea when that state is reached, only your application code does. Having Ionic check the scrollable content isn't a reliable fix because we would not be aware of any asynchronous requests that would cause the DOM to be updated and cause the scroll content check to be invalidated.
This results in a lot more effort than I thought because if you offer the load more button or want to check all this by yourself, you also need to implement a parallel prevention that the infinite load gets fired while you are loading content yourself without it. I was searching if there is some function to at least fire the event so that I don't need to do that but couldn't find anything. So the only way is to set the infinite load to disabled as soon as I do something and enable it again afterward, right?
When your loading function fires you'll want to either set disabled="true" on the button or remove it from the DOM entirely. You can also add a check to the function that returns early if another request is already in progress.
I updated the description of this issue to more accurately reflect the root problem (the event does not always fire when you scroll quickly).
@liamdebeasi Thank you so much, Liam. My maybe too trivial thought was: If the ion-infinite is visible inside the viewport, then content needs to be loaded and that can be the case because it's visible right away or it gets visible when you scroll down. If somebody scrolled too fast and ion-infinite is in the viewport but complete() hasn't been called yet, you would do the check immediately afterward and both issues would be solved. But maybe you are right and these are 2 completely different use cases although they felt naturally connected to me.
Alternatively, a function to trigger ion-infinite would help to prevent the double-check to disable ion-infinite if something is loading already which basically every app has to do. I am currently testing an intersection observer directive to solve the issue in a natural way but it needs further testing.
I really like the idea you suggested of removing it from the DOM entirely or disabling it, but wouldn't that exacerbate the problem because a user is scrolling a bit faster, the component is removed from the DOM, the API is finished loading, and while I add ion-infinite to the DOM again the user already did hit the bottom of the page and the ion-infinite won't trigger again because of the same reason again.
Sorry for so much text, I hope I am not totally wrong with my thoughts, and if you think so you can always overrule me of course. Anyway thank you very much for all your efforts, I really appreciate it.
I really like the idea you suggested of removing it from the DOM entirely or disabling it, but wouldn't that exacerbate the problem because a user is scrolling a bit faster, the component is removed from the DOM, the API is finished loading, and while I add ion-infinite to the DOM again the user already did hit the bottom of the page and the ion-infinite won't trigger again because of the same reason again.
To be clear, I am suggesting that you remove the ion-button (the button that lets users manually load more data) from the DOM, not ion-infinite-scroll. You can disable the ion-button when loading starts, and then remove it altogether once loading finishes (or just remove it when loading starts)
@liamdebeasi Okay, I misunderstood that, thank you. Makes sense but I still have to block the ion-infinite when content needs to be loaded for other reasons like the initial load when the list isn't long enough. This is where a trigger function could maybe help. But since I am no pro when it comes to maintaining a framework it's just open feedback/thoughts I am giving and I will try to work on some of your suggested or other workarounds.
Can everyone try the following dev build and let me know if it resolves the reported issue? It would be great if you could test the position="bottom" and position="top" use cases on ion-infinite-scroll. The team has done testing internally, but we'd love more testing from the community.
Note: This dev build only resolves the bug where scrolling down quickly does not always cause ionInfinite to fire. The other issue noted in this thread was determined not to be a bug in #18071 (comment).
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Activity
daem0ndev commentedon Apr 24, 2019
Happy to look into this one, we also ran into this and for now just used a very large default page size, but it would be nice if the component invoked the infinite method until it fills the viewable area. The important part is to make sure it stops requesting if the list doesn’t grow (there truly are no more items)
Chris1234567899 commentedon Nov 13, 2019
Any news on this?
This bug is unsolved since ionic 2.x I think :(
fr3fou commentedon Jul 26, 2021
will this be fixed with ionic 6?
acommend commentedon Apr 28, 2022
Just encountered this with v6.1.3 with ionic-vue. While in dev mode with a browser one can shrink the browser to create a scrollbar to trigger the scroller but this trick will not work when the app is deployed (only tested android). Anyone have a workaround to trigger the scroll for a deployed app if only a few items are on the page?
Chris1234567899 commentedon Apr 29, 2022
I wrote a hacky workaround back then - use at your own risk:
Just add the directive to your ion-infinite-scroll
Probably not the nicest solution, but better than nothing.
acommend commentedon Apr 29, 2022
@Chris1234567899 thanks for the workaround but unfortunately it won't work in my use case as each scroll action is associated with a chunk of time which may or may not have any items for that time range. Moreover I do not know the total number of items. If a scroll bar is present I have the component working to pull the next chunk of data for the next time range however if no scroll bar exists or the scrollbar that exists doesn't pass the threshold check the component will do nothing. One thought I had of was using the ion-refresher component for my use case however it doesn't support an option to use it at the bottom of the page. I may end up just adding a fab to trigger loading the next chunk of data instead of using the infinite scroll component or if time permits work with the team providing the API I'm using to get data to add a method to page the data by number of items instead.
derWebdesigner commentedon Jun 22, 2022
Glad to see that not only I am having issues with this extremely frustrating issue. For me, it's happening when I am scrolling a bit faster and the API is not responding quickly enough. With very fast scrolling I could even reproduce the issue in the Ionic documentation.
It's always loading 2 times and then it stops working. I also posted this issue in the Ionic forums but didn't get any response. The issue occurs when you reach the ion-infinite-scroll-content before complete() was called. What can solve it is to simply call complete() immediately before loading the data but then you have to solve the issue that the API could answer with page 3 before page 2.
derWebdesigner commentedon Jun 23, 2022
An additional hint after testing it quite a lot on different devices: This issue seems to only affect Android devices and browsers which could be the case because Apple has this rubberband effect that seems to help since scrolling is not stopping at a very strict position. But that's just an assumption.
Nevvulo commentedon Aug 1, 2022
I know this is fairly old so apologies for bumping, but this is still an issue when testing with
@ionic/reactv6.1.9, are there any plans for Ionic to support better behaviour when there's an infinite list with not enough elements to initiate scrolling? I agree with the OP's expected behaviour, I'd also expectionInfiniteto fire more than once if there are more items availablefishcolin commentedon Nov 4, 2022
Bummed to see this is still an issue :(
13 remaining items
liamdebeasi commentedon Oct 5, 2023
Thanks for the clarification. I'm not sure how Ionic would account for this in a general sense (i.e. for many use cases) since we don't know when your inner content is loaded. This still seems like an implementation issue. However, I can think of a few options to avoid this:
As you noted above above, this isn't always feasible especially with devices that have large screens such as tablets. You would potentially be loading 50+ items at once which can have negative performance implications.
This is a slightly more sophisticated version of option 1 where you load in increments of
nuntil your content can scroll. You could implement something like this:a. Load
ndata points.b. Check if your content can scroll. (check If the height of the list > height of the content visible area)
c. If your page can scroll then you are done.
d. If the page cannot scroll then load
nmore data points and go back to step a and repeat.You could show this button so users can manually fetch more data. Once data has been fetched or when the infinite scroll event fires then you can hide the button.
Do any of these work for your use case?
derWebdesigner commentedon Oct 6, 2023
@liamdebeasi Thank you, I definitely got your point. I still think (if possible) that the component should check if it reached the "I should load the next page"-state but currently isn't because there is no actual scroll event possible or happening. Adding a very subtle "load more" button is a good idea for sure and I will probably add it now as a workaround but I am sure that others using the component are not even aware of these "restrictions" and are therefore delivering broken endless scroll pages. On iOS the first issue is a bit less affected because you have the bounce scroll and if the user pushes a bit more the event suddenly fires sometimes but that feels anything else than smooth.
So basically checking more often if the scroll area is visible and firing a scroll event based on that manually is probably the only viable option I see, isn't it?
Thank you anyway for your thoughts and efforts, I highly appreciate them and I hope you can understand my perspective that I would love to provide a smooth experience and this would help a lot if it was solved somehow.
Edit: This results in a lot more effort than I thought because if you offer the load more button or want to check all this by yourself, you also need to implement a parallel prevention that the infinite load gets fired while you are loading content yourself without it. I was searching if there is some function to at least fire the event so that I don't need to do that but couldn't find anything. So the only way is to set the infinite load to disabled as soon as I do something and enable it again afterward, right?
Sorry for so much content but when I google for the issue I see lots of people having the same issue, trying to solve it somehow for over 5 years (which is when I recognized the issue the first time) and all of these approaches might look okay but they actually aren't for various reasons.
[-]bug: Infinite scroll not always working when few items are loaded[/-][+]bug: infinite scroll event does not fire if quickly scrolled[/+]liamdebeasi commentedon Oct 9, 2023
Yeah that's my point: Ionic has no idea when that state is reached, only your application code does. Having Ionic check the scrollable content isn't a reliable fix because we would not be aware of any asynchronous requests that would cause the DOM to be updated and cause the scroll content check to be invalidated.
When your loading function fires you'll want to either set
disabled="true"on the button or remove it from the DOM entirely. You can also add a check to the function that returns early if another request is already in progress.I updated the description of this issue to more accurately reflect the root problem (the event does not always fire when you scroll quickly).
derWebdesigner commentedon Oct 9, 2023
@liamdebeasi Thank you so much, Liam. My maybe too trivial thought was: If the ion-infinite is visible inside the viewport, then content needs to be loaded and that can be the case because it's visible right away or it gets visible when you scroll down. If somebody scrolled too fast and ion-infinite is in the viewport but complete() hasn't been called yet, you would do the check immediately afterward and both issues would be solved. But maybe you are right and these are 2 completely different use cases although they felt naturally connected to me.
Alternatively, a function to trigger ion-infinite would help to prevent the double-check to disable ion-infinite if something is loading already which basically every app has to do. I am currently testing an intersection observer directive to solve the issue in a natural way but it needs further testing.
I really like the idea you suggested of removing it from the DOM entirely or disabling it, but wouldn't that exacerbate the problem because a user is scrolling a bit faster, the component is removed from the DOM, the API is finished loading, and while I add ion-infinite to the DOM again the user already did hit the bottom of the page and the ion-infinite won't trigger again because of the same reason again.
Sorry for so much text, I hope I am not totally wrong with my thoughts, and if you think so you can always overrule me of course. Anyway thank you very much for all your efforts, I really appreciate it.
liamdebeasi commentedon Oct 9, 2023
To be clear, I am suggesting that you remove the
ion-button(the button that lets users manually load more data) from the DOM, notion-infinite-scroll. You can disable theion-buttonwhen loading starts, and then remove it altogether once loading finishes (or just remove it when loading starts)derWebdesigner commentedon Oct 9, 2023
@liamdebeasi Okay, I misunderstood that, thank you. Makes sense but I still have to block the ion-infinite when content needs to be loaded for other reasons like the initial load when the list isn't long enough. This is where a trigger function could maybe help. But since I am no pro when it comes to maintaining a framework it's just open feedback/thoughts I am giving and I will try to work on some of your suggested or other workarounds.
liamdebeasi commentedon Nov 21, 2023
Hi everyone,
Can everyone try the following dev build and let me know if it resolves the reported issue? It would be great if you could test the
position="bottom"andposition="top"use cases onion-infinite-scroll. The team has done testing internally, but we'd love more testing from the community.Dev build:
7.5.4-dev.11700602203.1e7155a1Install Example:
Note: This dev build only resolves the bug where scrolling down quickly does not always cause
ionInfiniteto fire. The other issue noted in this thread was determined not to be a bug in #18071 (comment).liamdebeasi commentedon Dec 5, 2023
Thanks for the issue. This has been resolved via #28569, and a fix will be available in an upcoming minor release of Ionic Framework.
fix(infinite-scroll): remaining in threshold after ionInfinite can tr…
ionitron-bot commentedon Jan 4, 2024
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.