Skip to content

Add virtual scrolling for panel/grid views using TanStack Virtual#1683

Open
apophisnow wants to merge 5 commits into
music-assistant:mainfrom
apophisnow:perf/panel-virtual-scroll
Open

Add virtual scrolling for panel/grid views using TanStack Virtual#1683
apophisnow wants to merge 5 commits into
music-assistant:mainfrom
apophisnow:perf/panel-virtual-scroll

Conversation

@apophisnow

Copy link
Copy Markdown
Contributor

No description provided.

@stvncode stvncode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Love tanstack virtualizer!
On top of that, can you add aria-rowcount/aria-rowindex for screen reader support on the virtualized list pls ?

const genreOptions = ref<{ label: string; value: number }[]>([]);

// virtual scroll setup for panel views
const scrollContainerRef = ref<HTMLElement | null>(null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we use this ref as a ref<HTMLElement | null>(null) instead of a document.querySelector('.content-section') ?

});

const panelRowHeight = computed(() => {
return viewMode.value === "panel_compact" ? 180 : 260;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why use harcoded value here ? Could we not match the actual rendered row heights ? If they don't match, the virtualizer will produce layout jumps as it measures real elements

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could be nice to use TanStack Virtual's measureElement


let _unsubscribeMediaEvents: (() => void) | undefined;
onBeforeUnmount(() => {
scrollContainerRef.value?.removeEventListener("scroll", checkInfiniteScroll);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you add { passive: true } to both addEventListener and removeEventListener pls ?It's recommended for scroll listeners to avoid jank

Comment thread src/components/ItemsListing.vue Outdated
v-for="item in panelRows[virtualRow.index]"
:key="item.uri"
cols="12"
:class="`col-${panelViewItemResponsive($vuetify.display.width)}`"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is called inside the v-for template via :class binding. Since this is already computed via columnCount, maybe we can use columnCount.value here instead of re-calling the function for every column in every virtual row

apophisnow and others added 3 commits April 7, 2026 08:11
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use template ref + closest() instead of document.querySelector
- Use TanStack Virtual measureElement for dynamic row heights
- Add { passive: true } to scroll event listener
- Use columnCount computed instead of re-calling panelViewItemResponsive
- Add aria-rowcount/aria-rowindex for screen reader support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@apophisnow apophisnow force-pushed the perf/panel-virtual-scroll branch from 56dc67a to eea5cca Compare April 7, 2026 15:13
apophisnow and others added 2 commits April 7, 2026 08:26
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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