Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VirtualList] Flickers when used with asynchronous rendering (e.g., React) #5982

Closed
Lodin opened this issue Jun 16, 2023 · 5 comments · Fixed by #6600
Closed

[VirtualList] Flickers when used with asynchronous rendering (e.g., React) #5982

Lodin opened this issue Jun 16, 2023 · 5 comments · Fixed by #6600

Comments

@Lodin
Copy link

Lodin commented Jun 16, 2023

Description

Investigating vaadin/react-components#88 issue, I found the following bug: when the item container is rendered, by default it has the following css styles:

<div style="position: absolute, transform: translateY(0px), padding-top: 25px"></div>

However, when the actual rendering happens (the container gets the internal content) the padding-top style is removed. For the regular rendering (including Lit) it happens in the same rendering cycle of the browser. But React does it more asynchronously, so for elements rendered by React we see a little flickering.

In vaadin/react-components#123, I have successfully fixed that issue by tweaking the container: I manually remove padding-top in the original cycle, and everything works as expected.

As far as I understand, the issue is caused by something inside the iron-list element.

My fix is a mere hack, so it would be great if that issue is fixed in its root.

Expected outcome

No flickering should be caused when using asynchronous rendering.

Minimal reproducible example

vaadin/react-components#88

Steps to reproduce

git clone https://github.com/vaadin/react-components.git
cd react-components
git checkout fix/ui-flickering-repro
npm i
npm run dev

Then open the app and scroll to the top. There will be two lists side by side; adding an item causes flickering in the left one.

Environment

Vaadin version(s): 24.1.0
OS: Windows 11

Browsers

Chrome

@tomivirkki
Copy link
Member

tomivirkki commented Jun 16, 2023

The padding-top is used as a placeholder for items that would otherwise temporarily render 0px high (due to async rendering).

Iron list will try to fill the viewport (+ some extra) with the items and if the items would be 0px high, you'd end up with a very large number of items in the DOM.

In your PR, will the list end up with too many item elements in the DOM due to the manual removal of padding-top for the original cycle?

@Lodin
Copy link
Author

Lodin commented Jun 16, 2023

Good question.
Just checked: it looks like nothing wrong happens. There are 20 elements for both virtual lists while I have added about 100. Scrolling, adding elements after the scroll seems equal for both cases. Does it mean that everything is ok?

@tomivirkki
Copy link
Member

Maybe. The placeholder was still added to the virtualizer for a good reason. Could be that removing it backfires eventually even though it works in this case.

@Lodin
Copy link
Author

Lodin commented Jun 16, 2023

Yeah, that's why I made my PR more like a patch while the root of the issue is being fixed. Is it possible to fix?

I also thought that I could add additional condition that checks the computed height of an element and if it is 0, then I don't remove the padding. What do you think about this solution?

@tomivirkki
Copy link
Member

Once the 0-height item actually receives some content and its height changes, the ResizeObserver in Virtualizer is what reacts to it and removes the placeholder padding.

The delay between the content appearing inside the item element and the observer reacting to it is probably what causes the flickering.

One possible fix could be to make virtualizer use visibility: hidden for items that are in the "placeholder" mode. Another fix could be to flush the ResizeObserver externally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants