According to the official documentation of angular virtual scrolling minBufferBx and maxBufferPx
Supposed that we have the following parameters: itemSize = 50, minBufferPx = 100, maxBufferPx = 250. As the user is scrolling through the content the viewport detects that there is only 90px of buffer remaining. Since this is below minBufferPx the viewport must render more buffer. It must render at least enough buffer to get back to maxBufferPx. In this case, it renders 4 items (an additional 200px) to bring the total buffer size to 290px, back above maxBufferPx.
So I understand that so if the my visible viewport height is 250px, then the virtual scroll viewport will be rendered between 350px and 500px. And so when i searching for infinity scrolling support, most tutorial provided with the below code.
const end = this.viewport.getRenderedRange().end;
const total = this.viewport.getDataLength();
console.log(`${end}, '>=', ${total}`);
if (end === total) {
this.offset.next(offset);
}
The above code what i understand is that if the viewport rendered range end is equal to the current retrieved data length, then will request next batch of data. The rendered range end is equal to the item index between minBufferPx and maxBufferPx. For example, if the content window height is 250px, item height is 50px, the firstVisibleIndex is at item index 2, set minBufferPx= 350, maxBufferPx=350, then according to the above minBufferPx, the rendered range end item is at least at index 12. So if end === total, then request next batch.
But according to my implementation code, the actual is not like that.
<cdk-virtual-scroll-viewport
itemSize="64" minBufferPx="64*20" maxBufferPx="64*35" (scrolledIndexChange)="scrollIndexChange($event)">
scrollIndexChange(firstVisibleIndex: number) {
if (this.previousFirstVisibleIndex < firstVisibleIndex &&
this.scrollViewPort.getDataLength() === this.scrollViewPort.getRenderedRange().end) {
this.logService.logger.debug(this.tag + 'scroll index change: request next: firstVisibleIndex:' + firstVisibleIndex + ', ',
this.scrollViewPort.getDataLength() + ', ' + this.scrollViewPort.getRenderedRange().end);
// get next batch contact list
this.getNextBatch();
}
My content widow height is 576px, it can put 9 items in the visible range. And i monitor my scrolling behavior and checking the request of next match log
scroll index change: request next: firstVisibleIndex: 26, dataLength: 35, renderedRange end: 35
scroll index change: request next: firstVisibleIndex: 54, dataLength: 63, renderedRange end: 63
scroll index change: request next: firstVisibleIndex: 85, dataLength: 94, renderedRange end: 94
scroll index change: request next: firstVisibleIndex: 118, dataLength: 127, renderedRange end: 127
What i discovered is that minBufferPx, maxBufferPx is not working as i expected. FirstVisibleIndex and renderedRange end always difference 9 items which is the visible window height. So according to the above implementation, infinity scrolling experience is not good. It only request next batch when scrolling reach at the end.
So i tried to modify my code like below to test for better scrolling experience.
if (this.previousFirstVisibleIndex < firstVisibleIndex && firstVisibleIndex + 20 >= this.scrollViewPort.getDataLength()) {
this.logService.logger.debug(this.tag + 'scroll index change: request next: firstVisibleIndex:' + firstVisibleIndex + ', ',
this.scrollViewPort.getDataLength() + ', ' + this.scrollViewPort.getRenderedRange().end);
this.getNextBatch()
}
This above code somehow like keeping buffer of 11 items, and request next batch. The above way is not good also, because i use the constant 20 number. if the content window changed to put 21 items, this code will have the issue.
I would like to ask if my understanding of minbufferPx and maxBufferPx wrong? it is not reflected in the getRenderedRange().end?