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

[virtualizer] Scroll offset is not always restored after size change #7237

Open
vursen opened this issue Mar 19, 2024 · 2 comments
Open

[virtualizer] Scroll offset is not always restored after size change #7237

vursen opened this issue Mar 19, 2024 · 2 comments

Comments

@vursen
Copy link
Contributor

vursen commented Mar 19, 2024

Description

Follow-up to #7205

The virtualizer doesn't always restore the first visible item's scroll offset after the size change. This tends to happen when the list size > 100 000 and the size change doesn't affect the currently visible items.

Expected outcome

The scroll offset should be restored after the size change.

Minimal reproducible example

it('should preserve scroll position when size decrease does not affect any rendered indexes', async () => {
  // Scroll to an index and add an additional scroll offset.
  const index = virtualizer.size - 2000;
  virtualizer.scrollToIndex(index);
  scrollTarget.scrollTop += 10;

  // Decrease the size so that no rendered indexes are affected.
  virtualizer.size -= 1000;
  await oneEvent(scrollTarget, 'scroll');

  const item = elementsContainer.querySelector(`#item-${index}`);
  expect(item.getBoundingClientRect().top).to.be.closeTo(scrollTarget.getBoundingClientRect().top - 10, 1);
});

it('should preserve scroll position on size increase', async () => {
  const index = virtualizer.size - 2000;
  virtualizer.scrollToIndex(index);
  scrollTarget.scrollTop += 10;

  virtualizer.size += 1000;
  await oneEvent(scrollTarget, 'scroll');

  const item = elementsContainer.querySelector(`#item-${index}`);
  expect(item.getBoundingClientRect().top).to.be.closeTo(scrollTarget.getBoundingClientRect().top - 10, 1);
});

Steps to reproduce

--

Environment

Vaadin version(s): 24.4

Browsers

No response

@vursen vursen added bug Something isn't working vaadin-virtual-list labels Mar 19, 2024
@vursen
Copy link
Contributor Author

vursen commented Mar 19, 2024

The scroll offset appears to be reset by _adjustVirtualIndexOffset that is called on scroll event following scrollToIndex that restores the scroll position.

@vursen vursen changed the title [virtualizer] Does not always restore scroll offset after size change [virtualizer] Scroll offset is not always restored after size change Mar 19, 2024
@vursen
Copy link
Contributor Author

vursen commented Mar 19, 2024

I made an attempt to fix the issue by skipping _adjustVirtualIndexOffset in _scrollHandler if the scroll position hasn't changed since the previous scroll event. However, it revealed that the _adjustVirtualIndexOffset call – happening on scroll event that follows scrollToIndex – is important. At least, the scroll height doesn’t get always updated correctly without it. It's curious because scrollToIndex has its own logic updating _vidxOffset and I would expect no need for any further adjustments.

Besides, I noticed that scrolling to an index near the end of a large list can cause _adjustVirtualIndexOffset to be called just as many times as there are items rendered in the DOM. The reason is again scrollToIndex apparently calculating _vidxOffset inaccurately so that another adjustment is needed on the following scroll event.

image

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

No branches or pull requests

2 participants