Skip to content

Expose API to update size cache for VList/Virtualizer #885

Description

@Horuse

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.

  1. User updates data, so the same index now references a different item.
  2. virtua renders with the stale cached height (_sizes[index]).
  3. ResizeObserver delivers new sizes, ACTION_ITEM_RESIZE in
    src/core/store.ts computes a jump and bumps stateVersion.
  4. The effect tied to stateVersion calls scroller.$fixScrollJump(),
    writing scrollTop += jump.
  5. 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

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions