angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.37k stars 6.75k forks source link

bug(cdk-virtual-scroll): Scrolling fast makes the viewport blank until scrolling stops #20971

Open Harpush opened 4 years ago

Harpush commented 4 years ago

Reproduction

https://stackblitz.com/edit/angular-qxcwbr

Steps to reproduce: There are two virtual scroll viewports - the first has the problem. Take the scroll bar with the mouse and scroll down fast. The whole viewport will be blank as long as you scroll. The second viewport uses a bizarre fix and if you try the same it will magically work.

Expected Behavior

Both of the viewports should scroll without viewport going blank

Actual Behavior

Without the bizarre fix the viewport becomes blank while fast scrolling

Environment

hakimio commented 4 years ago

How did you find out about the "fix":

<div style="position: absolute; top:0; left:0; width:100%; height:100%; pointer-events:none"></div>
Harpush commented 4 years ago

How did you find out about the "fix":

<div style="position: absolute; top:0; left:0; width:100%; height:100%; pointer-events:none"></div>

Because it didnt have the problem in another app and after i investigated i saw cdk overlay "fixed" it. And that's how i got to it.

mmalerba commented 4 years ago

This is actually done intentionally so that we're not constantly rendering new elements while the user is rapidly scrolling which would be detrimental to performance. However, there is probably some room to improve this by showing some kind of lightweight placeholder elements so the user doesn't think its lagging.

Harpush commented 4 years ago

@mmalerba The lightweight placeholder idea is a great idea! Hope it can be added as opt in. The only mystery left is the so called fix using the absolute positioned div

briancodes commented 3 years ago

@mmalerba The lightweight placeholder idea is a great idea! Hope it can be added as opt in. The only mystery left is the so called fix using the absolute positioned div

This seems to be Chrome related. Thankfully the workaround you provided fixes it👍 Was not able to reproduce the issue in Firefox or Safari

Note: I also reproduced this bug in Chrome using a very long list of elements (>50,000) without the cdk - and again the position:absolute fix worked there too

minimalism commented 3 years ago

This is actually done intentionally so that we're not constantly rendering new elements while the user is rapidly scrolling which would be detrimental to performance. However, there is probably some room to improve this by showing some kind of lightweight placeholder elements so the user doesn't think its lagging.

It would be great to be able to configure which strategy the virtual scroll uses to deal with this, as it seems many users experience the view to be slower when they see this visual pop-in effect, compared to a slight delay during the scrolling that doesn't leak the details of the virtual scroll strategy. (though I understand the total time spent by the render thread in the former case is much lower)

KVikram commented 3 years ago

How did you find out about the "fix":

<div style="position: absolute; top:0; left:0; width:100%; height:100%; pointer-events:none"></div>

This is a really weird but helpful fix to this issue. Thanks @Harpush ! Also noticed in your example, if I remove the style="position: relative" from the second box then the blank viewport issue doesn't occur in first box as well.

Here is the sample - https://stackblitz.com/edit/angular-qxcwbr-lyk95e?file=src%2Fapp%2Fcdk-virtual-scroll-context-example.html

Anyways, there must be some kind of explanation for this behaviour and proper workaround will be helpful and mostly useful.

jeanieherold commented 3 years ago

what a bizarre fix indeed but it sure did fix that.. it was driving me crazy. grateful for the share here!

similar to that... any one noticed that the cdk virtual on a dropdown (I have it on a custom data table dropdown - once you scroll the list and make a choice - then reopen the dropdown - the list is blank until you start scrolling the list... any fixes anyone know of?

as soon as you start scrolling the list shows up

doesnt happen everytime but does happen more than 50% of the time on a large list

zhaoyao91 commented 2 years ago

How to fix the "fix" in chrome? In our senary, we need both the "white screen" effect and the fixed element to lay over the list as a wartermark, but the wartermark erases the white screen effect, whch leads to the list scrolling stuck since before the item being fully rendered, the scroll process seems to be interrupted. but with the white screen effect, even though the cost of rendering item is heavy, the scrolling is always smoothy and the item will becom white and will finally be renderred after sometime, this is prefered.

scroll with white screen(prefered) https://user-images.githubusercontent.com/3808838/196651792-d8fd6b67-faa8-4177-be54-4a7dc99064c1.mp4

scroll without white screen( stuck, not prefered, but we do need the fixed wartermark) https://user-images.githubusercontent.com/3808838/196651975-3a95181e-d060-4fae-a67a-5c4eb1d185d0.mp4

codesandbox demo: https://codesandbox.io/s/bold-beaver-3l41sk?file=/index.js

UPDATED

this comment is covered here https://github.com/bvaughn/react-window/issues/455#issuecomment-618020522

thanks, closed.

ruminize commented 1 year ago

what a bizarre fix indeed but it sure did fix that.. it was driving me crazy. grateful for the share here!

similar to that... any one noticed that the cdk virtual on a dropdown (I have it on a custom data table dropdown - once you scroll the list and make a choice - then reopen the dropdown - the list is blank until you start scrolling the list... any fixes anyone know of?

as soon as you start scrolling the list shows up

doesnt happen everytime but does happen more than 50% of the time on a large list

What is currently working for me in this situation: repeated opening of dropdown presents blank content until re-scrolled, is to call the QueryList first item, call scroll on that item, then set scrolltop of the scroll container to 0. Then wrap it up in a friendly "force it to the bottom of the call stack" setTimeout.

// Do this at the end of your open click event or down arrow call. setTimeout(() => { const element = this.optionsList.find((option, index) => index === 0); element.nativeElement.scrollIntoView(); this.scrollListElement.nativeElement.scrollTop = 0; }):

When the dropdown opens again, the content is there and I do note a slight appearance of the scroll bar appearing in the top right corner for a brief moment, but the contents is stable and you don't see it actually scroll even if the user scrolled before opening it up the second time.

Note: This was working a year ago with just setting the scrolltop to 0, but as of 9/9/2023 it now requires the above and in that order.

Second Note: Depending on on how your code works with focus and blur as well, I did get this.scrollListElement.nativeElement.scrollTop = 0; to work again by itself without the above first two lines with element.

In my case, I have an input (autocomplete) that works with the dropdown. When any activity occurs in the drop-down, it triggers the blur event, which always calls this.element.nativeElement.focus(); This is to return focus back to the input.

This may also have something to do with it. In any case, keep trying there are ways to get it to work. I no longer have the blank issue.

Bullsized commented 8 months ago

Running Angular v17 the div at the bottom fix is not working - any other recommendations? Or could we display some sort of a placeholder until the list renders the items to the scrolled location?

kapil26021994 commented 2 weeks ago

Any update ln above issue still i am facing above issue?