-
-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[performance] Virtualise CommandItem when trying to display large lists? #80
Comments
This is going to be improved in the Svelte 5 version for sure 😃 For example, here's a list of 2,000 items running on Svelte 5 version (coming soon): CleanShot.2024-09-20.at.21.58.40.mp4Something to note about this project that differs from a traditional combobox is that it's actually sorting/ranking the dom elements whereas the combobox simply filters. |
@NathanAdhitya I had the same issue. For this, I created an component that wraps the virtua lib (because of shadcn-svelte folder convention, but you can call directly if you want).
<script lang="ts" context="module">
import { VList } from 'virtua/svelte';
import type { ComponentEvents, ComponentProps } from 'svelte';
</script>
<script lang="ts">
type T = $$Generic;
type $$Props = ComponentProps<VList<T>>;
type $$Events = ComponentEvents<VList<T>>;
type $$Slots = { default: { item: T; index: number } };
export let data: $$Props['data'] = [];
</script>
{#key data.length}
<VList {data} {...$$restProps} let:item let:index>
<slot {item} {index} />
</VList>
{/key} Then, I use it together with the <script>
import * as Command from '$lib/components/ui/command';
import { VirtualList } from '$lib/components/ui/virtual-list';
</script>
<Command.Root shouldFilter={false} class="size-auto rounded-none bg-transparent">
<Command.Input
placeholder="Search item..."
value={$searchTerm}
on:input={debounceSearch.call}
class="h-10 py-2"
/>
<Command.List class="h-[20svh] [&>div]:contents">
<Command.Empty class="py-4">No results</Command.Empty>
{#if $filtered.length}
<Command.Group alwaysRender class="h-full p-0 [&>div]:h-full">
<VirtualList
data={$filtered}
getKey={(item) => item.name}
let:item={option}
class="overflow-y-auto p-2"
>
<Command.Item value={option.name} class="shrink-0 gap-3 !bg-transparent">
<Checkbox
id={option.name}
aria-labelledby={option.name}
bind:checked={$options[option.name].checked}
on:click={debounceFilter.call}
/>
<Label id={option.name} for={option.name} class="w-full">
{option.name}
</Label>
</Command.Item>
</VirtualList>
</Command.Group>
{/if}
</Command.List>
</Command.Root> |
As title says.
I'm personally trying to make it working by integrating TanStack Virtual.
It's not going very well. Extremely janky, but cut initial mount time (around 600 elements, Combobox element from shadcn-svelte) from 2-3s after clicking the Popover.Trigger to perceivably instant. I haven't gotten filtering to work yet.
Has anyone gotten this issue, if so, what solutions helped?
The text was updated successfully, but these errors were encountered: