Is your feature request related to a problem? Please describe.
With variable-height items in <VList> / <Virtualizer>, a drag-and-drop reorder produces a one-frame flicker (~1-2px shift, sometimes more) before the layout settles.
virtua's size cache is keyed by index (Cache._sizes[i] in src/core/cache.ts), so after reordering items in the data array the same index points to a different item with a different real height.
- User updates
data, so the same index now references a different item.
- virtua renders with the stale cached height (
_sizes[index]).
ResizeObserver delivers new sizes, ACTION_ITEM_RESIZE in
src/core/store.ts computes a jump and bumps stateVersion.
- The effect tied to
stateVersion calls scroller.$fixScrollJump(),
writing scrollTop += jump.
- Browser already painted one frame with stale heights, hence the flicker.
Lists with uniform heights don't reproduce this because cached values remain valid after permutation. The repo's existing dnd-kit story uses uniform heights, which is why it doesn't surface the issue.
Describe the solution you'd like
Some way to update the index/size mapping from user code before the reorder lands, so that the subsequent ResizeObserver callback finds the cache already consistent and skips its correction pass.
for example:
vlist.setItemSizes([[0, h0], [1, h1], ...]);
Describe alternatives you've considered
requestAnimationFrame + scrollBy(delta). Always lands at least
one frame after virtua's own $fixScrollJump, leaving sub-pixel jitter.
scrollTo(getScrollOffset()) save/restore. Produces an extra scroll
event, perceived as double jitter.
Additional context
Example (virtua + dnd-kit): https://stackblitz.com/edit/vitejs-vite-4xibpcqs?file=src%2FApp.tsx
Is your feature request related to a problem? Please describe.
With variable-height items in
<VList>/<Virtualizer>, a drag-and-drop reorder produces a one-frame flicker (~1-2px shift, sometimes more) before the layout settles.virtua's size cache is keyed by index (
Cache._sizes[i]insrc/core/cache.ts), so after reordering items in thedataarray the same index points to a different item with a different real height.data, so the sameindexnow references a different item._sizes[index]).ResizeObserverdelivers new sizes,ACTION_ITEM_RESIZEinsrc/core/store.tscomputes a jump and bumpsstateVersion.stateVersioncallsscroller.$fixScrollJump(),writing
scrollTop += jump.Lists with uniform heights don't reproduce this because cached values remain valid after permutation. The repo's existing dnd-kit story uses uniform heights, which is why it doesn't surface the issue.
Describe the solution you'd like
Some way to update the index/size mapping from user code before the reorder lands, so that the subsequent
ResizeObservercallback finds the cache already consistent and skips its correction pass.for example:
Describe alternatives you've considered
requestAnimationFrame+scrollBy(delta). Always lands at leastone frame after virtua's own
$fixScrollJump, leaving sub-pixel jitter.scrollTo(getScrollOffset())save/restore. Produces an extra scrollevent, perceived as double jitter.
Additional context
Example (virtua + dnd-kit): https://stackblitz.com/edit/vitejs-vite-4xibpcqs?file=src%2FApp.tsx