Skip to content

Make VirtualList scroll fast#12661

Merged
mtsgrd merged 1 commit intomasterfrom
virtuallist-perf
Mar 3, 2026
Merged

Make VirtualList scroll fast#12661
mtsgrd merged 1 commit intomasterfrom
virtuallist-perf

Conversation

@mtsgrd
Copy link
Copy Markdown
Contributor

@mtsgrd mtsgrd commented Mar 3, 2026

Reduce per-scroll-frame work from O(items) to O(visibleItems + delta)

  • Avoid unnecessary initialization when target already rendered
  • Start visible-range scanning from renderRange.start using
    cached offset.top instead of always walking from index 0
  • Limit DOM height reads to elements inside the current render range
  • Replace redundant O(n) calculateHeightSum(0, renderRange.start)
  • Update top/bottom offsets incrementally (O(|rangeDelta|)) when
    the render range shifts, falling back to a full recompute only when
    the item count changes
  • Replace previousItems array clone with three scalars (previousLength,
    previousHeadId, previousTailId) to detect prepend/append/replace

Copilot AI review requested due to automatic review settings March 3, 2026 09:34
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gitbutler-web Ignored Ignored Preview Mar 3, 2026 10:16am

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes VirtualList scrolling performance by reducing per-scroll work, primarily by scanning visible ranges from the current render window using cached offsets and updating padding offsets incrementally.

Changes:

  • Update visible-range calculation to scan from renderRange.start using offset.top, avoiding always walking from index 0.
  • Incrementally update offset.top/offset.bottom when the render range shifts, falling back to full recompute when the item count changes.
  • Avoid previousItems array cloning by tracking previousLength and head/tail IDs, and add a jumpToIndex fast path when the target is already rendered.

Comment thread packages/ui/src/lib/components/VirtualList.svelte Outdated
Comment thread packages/ui/src/lib/components/VirtualList.svelte
Comment thread packages/ui/src/lib/components/VirtualList.svelte
Reduce per-scroll-frame work from O(totalItems) to O(visibleItems + delta)

- Start visible-range scanning from renderRange.start using cached
  offset.top instead of always walking from index 0
- Limit DOM height reads to elements inside the current render range
- Replace redundant O(n) calculateHeightSum(0, renderRange.start) with
  cached offset.top in compensateScrollForResize
- Update top/bottom offsets incrementally (O(|rangeDelta|)) when the
  render range shifts, falling back to full recompute only when item
  count changes
- Replace previousItems array clone with three scalars
  (previousLength, previousHeadId, previousTailId) to detect
  prepend/append/replace without O(n) copy
- Remove $state proxy from heightMap (never read in reactive context)
- Add jumpToIndex fast path: skip teardown when target is already in
  render range, compute scrollTop as offset.top + partial sum
  O(renderRange.size) instead of O(index)
- Cache repeated template expressions with {@const} in #each block
@mtsgrd mtsgrd force-pushed the virtuallist-perf branch from a46f684 to 37fd559 Compare March 3, 2026 10:16
@mtsgrd mtsgrd merged commit ba6b184 into master Mar 3, 2026
53 of 55 checks passed
@mtsgrd mtsgrd deleted the virtuallist-perf branch March 3, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants