fluentui icon indicating copy to clipboard operation
fluentui copied to clipboard

[Bug]: Virtualizer stops rendering updates when items are removed from the end

Open nkirchem opened this issue 7 months ago • 2 comments

Component

Virtualizer (Preview)

Package version

9.64.0

React version

18.3.1

Environment

any

Current Behavior

I'm leveraging Virtualizer to render a set of rows that can be added or removed. If the user is scrolled to the bottom of the list, and they start removing the last rows in the list, the virtualizer stops filling in the new (previous) rows which should start coming into the top of the viewport. The user can remove all the visible rows, then be left with a completely empty viewport. Even scrolling up/down at that point just shows an empty/blank content rather than showing the remaining rows.

Expected Behavior

When rows are needed at the top of the viewport, due to rows being removed from the bottom, they should be rendered.

The issue is due to this line: useVirtualizer.ts#L411

That block is there for a performance optimization, preventing re-rerenders if the user is already at the end of the list -- assuming that means it doesn't need to redraw anything above it. However, it doesn't consider this scenario, where the number of rows is changing between renders.

If I add: newStartIndex === actualIndex &&

to the start of that if condition, it fixes the issue. I have patched our repo's react-virtualizer package with this (pnpm patch) for now.

Reproduction

https://stackblitz.com/edit/gfsqkbfr?file=src%2Fexample.tsx

Steps to reproduce

  1. Scroll down to the bottom of the list
  2. Click the Remove button on the last row (Node 99)
  3. Repeat step 2 about 10 times (Node 98...90)

You'll be left with only a couple of rows (or no rows if you delete them all). They don't even recover after scrolling up/down.

Are you reporting an Accessibility issue?

None

Suggested severity

High - No workaround

Products/sites affected

Azure portal

Are you willing to submit a PR to fix?

yes

Validations

  • [x] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • [x] The provided reproduction is a minimal reproducible example of the bug.

nkirchem avatar Jun 04 '25 12:06 nkirchem

Hi @nkirchem 👋🏻

The condition is indeed changing this behaviour. However, since the component is not stable yet and not well documented, I suppose you might use wrong part of the API. The function you may noticed in the condition you updated is part of the public API and js-doc comment mentions A callback that enables updating scroll position for calculating required dynamic lengths, this should be passed in from useDynamicVirtualizerMeasure, so perhaps you just had to use useDynamicVirtualizerMeasure. I will ping owner of this component 🙂

@Mitch-At-Work can you confirm if it's a bug or not? 🙏🏻

mainframev avatar Jun 08 '25 22:06 mainframev

@mainframev thanks for looking. The repro here is just using the same code from the public samples, it only adds a button to remove each row. There doesn't appear to be any issue here with calculating scroll position and overall length. It is just an issue with the line mentioned above, which was added as a perf optimization (to bail on re-rendering if already at the end of the list), but fails to account for the fact that being at the end of the list doesn't always mean there is nothing to update. When the number of items is reduced between render cycles, the items at the start of the visible range need to be updated.

nkirchem avatar Jun 09 '25 11:06 nkirchem

Hi all, thank you for the bug report, I'll take a look at this soon as part of our migration to stable.

While newStartIndex === actualIndex will solve the problem, this will almost always be true which causes additional re-renders when not needed also.

The likely fix here is that we'll need to track when 'numItems' changes and re-calc when that occurs.

Mitch-At-Work avatar Jun 17 '25 16:06 Mitch-At-Work

Fix available here: https://github.com/microsoft/fluentui/pull/34673

Mitch-At-Work avatar Jun 17 '25 23:06 Mitch-At-Work