diprokon / ng-table-virtual-scroll

Virtual Scroll for Angular Material Table
https://diprokon.github.io/ng-table-virtual-scroll
MIT License
134 stars 42 forks source link

table jerks up and down #60

Closed AliceZhuZhu closed 1 year ago

AliceZhuZhu commented 3 years ago

when my chart slides a few times and then release the mouse, the chart content will fluctuate up and down. Similar to [https://github.com/diprokon/ng-table-virtual-scroll/issues/30]. But setting'tvsItemSize' with no value still cannot solve this problem for me.

My code: <cdk-virtual-scroll-viewport tvsItemSize [headerHeight]="64" [bufferMultiplier]="15" [ngStyle]="{'height': tableHeight, 'width': '100%'}"> <table mat-table [dataSource]="tableRows" matSort matSortActive="{{matSortActive}}" matSortDirection="{{matSortDirection}}" matSortDisableClear (matSortChange)="sortData($event)" matSortStart="desc" [multiTemplateDataRows]="true"> ... ... </table> </cdk-virtual-scroll-viewport>

And a blank area will appear on the chart when you swipe quickly.

My data is 1,800 pieces of more complex data. Will this have any effect?

AliceZhuZhu commented 3 years ago

I found that this is because the value of cdk-virtual-scroll-content-wrapper's transformhas been changing, but I can’t seem to fix it to a constant value. Is there any solution?

JoeyLi-1 commented 3 years ago

@diprokon We try to create a repo to reproduce the issue. It is not 100% same as it act in our project. The row rebound after you scroll up or down (up is more obviously). Refer to this screen record.

https://user-images.githubusercontent.com/20162464/119777934-6f65aa80-bef9-11eb-8571-a084a776a470.mp4

Though it is not as crazy as it act in our project. This one below.

https://user-images.githubusercontent.com/20162464/119778061-98863b00-bef9-11eb-8d02-886f08475b11.mp4

We already use pagination instead of virtual scroll. But if you have any idea about what is going wrong. That would be appreciated.

MaximeKoitsalu commented 2 years ago

I also am experiencing this table jerking behavior. @JoeyLi-1 Did you ever find a workaround? or a fix?

JoeyLi-1 commented 2 years ago

@MaximeKoitsalu Not yet. I guess it is something about redraw and calculation. Tight schedule, so did not have time to investigate. We use pagination instead of infinite scroll temporary. I will post here if I m lucky enough to find anything related or a workaround.

VangeM commented 2 years ago

Also experiencing this jerkiness on page up, and scrolling up. Also, the header row jumps down from the top when this happens. Sometimes it moves back to the top of the list, sometimes it just stays in the middle of the list.

oo8s commented 2 years ago

I'm also having same issue (latest version) when scrolling up, which makes the component unusable when there is a lot of items in the grid

@diprokon In the wiki examples (last one - Table with sticky column) we can see that when scrolling down it is scrolling 2 items but when scrolling up it is scrolling only 1 item. This is not the case for any of the other examples That could be related to the same issue.

JoeyLi-1 commented 2 years ago

Hey guys,

I had investigated this issue again. Seems it has nothing to do with this project. The viewport is very smart. It creates a "wrapper" to wrap the content you want to display. And a "spacer" which height equals to the total rows` length. It sets its position to absolute, so wrapper could slide on the spacer. image

The wrapper only contain certain amount of rows, not all the rows in the data set. const itemsDisplayed = Math.ceil(this.viewport.getViewportSize() / this.rowHeight); const bufferItems = Math.ceil(itemsDisplayed * this.bufferMultiplier); const end = start + itemsDisplayed + 2 * bufferItems; If the bufferMultiplier = 1 and one screen could display 20 rows. Then the wrapper will contain 20 + 2*20 = 60 rows.

When scroll event triggered. The viewport will call "onContentScrolled" function of the customized Strategy class. (https://github.com/angular/components/blob/master/src/cdk/scrolling/virtual-scroll-viewport.ts) image

And if you only scroll vertically, the current "scrollOffset" is the scrollTop of viewport. (https://github.com/angular/components/blob/master/src/cdk/scrolling/scrollable.ts) image

This project will only be notified when scroll event triggered. It does not know whether it is scroll up or down. It only knows the current scroll position. After some calculation, the customized Strategy will tell the wrapper to transform up / down. If there is no buffered content. "this.viewport.setRenderedContentOffset(adjustedRenderedOffset);"
(https://github.com/angular/components/blob/master/src/cdk/scrolling/virtual-scroll-viewport.ts) image

And then it will tell the dataset provider to prepare a new set of data set. " this.viewport.setRenderedRange({start: adjustedStart, end: adjustedEnd});" image

After this, if you are scrolling down. Assume you scroll 5 rows, the wrapper go up "translateY(5 * rowHeight px)". And the wrapper displayed from row 0 - 60 to row 5 - 65 now.

So it should work perfectly theoretically.

The issue what we encountered. Only happened when we set first some columns sticky. And then the tricky thing is: When I simply scroll down, it will automatically generate some scroll up event. Those wired scroll up event make the table jump up and down. image

As we can see from above, this project does not know a scroll event is scroll up / down. So there is nothing it can do against this issue.

So, I would suggest that if you want to use this project. Do not use it with complex table. Or use pagination instead. @MaximeKoitsalu

JoeyLi-1 commented 2 years ago

BTW, your project is excellent project. Thank you very much! :) @diprokon

MaximeKoitsalu commented 2 years ago

Thank you for taking time to write your answer! I appreciate your library

iamemiliano commented 1 year ago

Hello, I have the same problem with my virtual scroll. I tried all these solutions but it didn't work. Any other suggestions ? It works well before i updated my project to Angular 14.

<cdk-virtual-scroll-viewport class="table-container" [ngClass]="{ 'locked' : !!conducteur?.locked, 'extended': store.panelExtended }" [style.overflow]="draggingCases ? 'hidden': 'auto'" [bufferMultiplier]="15" [tvsItemSize]="20" [headerHeight]="42.5">

iamemiliano commented 1 year ago

@AliceZhuZhu Is there a solution ?

AliceZhuZhu commented 1 year ago

I had investigated this issue again. Seems it has nothing to do with this project. The viewport is very smart. It creates a "wrapper" to wrap the content you want to display. And a "spacer" which height equals to the total rows` length. It sets its position to absolute, so wrapper could slide on the spacer.

this https://github.com/diprokon/ng-table-virtual-scroll/issues/60#issuecomment-988656428

josephaVMW commented 1 year ago

Hey all, in case this helps anyone else who's seeing this issue - from my testing it seems that the movement up and down, as @JoeyLi-1 mentioned, pretty much always happens. If virtual scrolling is the only calculation happening on the page, the user will never notice it, and it may even be happening faster than Angular redraws the page. However, if you have a large number of getters or functions being called as part of the Angular update cycle, things slow down considerably and the user will notice this movement - sometimes to the point of the scroller being unusable.

So my suggestion to you is: See if you can stop (or hide behind an *ngIf) as many JS calculations as possible when virtual scrolling is active. Replace calculated styles with pure CSS where possible. Swap some getter functions for variables that are calculated once on update, instead of every change detection cycle.

I was ready to abandon virtual scrolling altogether, but after making the changes I mentioned above, it's now working as smoothly as in the demos.