Virtualization
Learn how to efficiently render large datasets with Reka UI, powered by @tanstack/virtual
.
What is Virtualization?
Virtualization is a technique used to efficiently render large lists or tree structures by only rendering the items currently visible in the viewport. This approach significantly improves performance and reduces memory usage, especially when dealing with thousands of items.
Benefits of Using Virtualization
- Improved Performance: Render thousands of items without lag
- Reduced Memory Usage: Only mount DOM nodes for visible items
- Better User Experience: Fast initial load times and responsive interactions
Customization Options
All virtualizer (Combobox, Listbox, and Tree) components offer the following props and customization:
- Custom item rendering: Flexibility to render complex item structures
estimateSize
: Set estimate item heights for static or dynamic itemoverscan
: Control the number of items rendered outside the visible areatextContent
: Text content for each item to achieve type-ahead feature
Usage
Here's a few important note to make sure virtualization works!
- A fixed height/max-height wrapping
<Virtualizer />
. - Consistent item height, and set the
estimateSize
props appropriately. - Set
textContent
props to make sure type-ahead acceessibility.
Example
vue
<script setup>
import { ComboboxContent, ComboboxItem, ComboboxRoot, ComboboxViewport, ComboboxVirtualizer } from 'radix-vue'
const items = [
// … large array of items
]
</script>
<template>
<ComboboxRoot>
…
<ComboboxContent>
<!-- Make sure to set a height for Virtualizer's parent element -->
<ComboboxViewport class="max-h-80 overflow-y-auto">
<ComboboxVirtualizer
v-slot="{ option }"
:options="items"
:estimate-size="25"
:text-content="(opt) => opt.label"
>
<ComboboxItem :value="option">
{{ option.label }}
</ComboboxItem>
</ComboboxVirtualizer>
</ComboboxViewport>
</ComboboxContent>
</ComboboxRoot>
</template>
Common issue
Virtualization is not working
Do ensure that <Virtualizer>
's parent element has a defined height!
vue
<template>
<ComboboxRoot>
…
<ComboboxContent>
<!-- Height must be defined -->
<ComboboxViewport class="max-h-80 overflow-y-auto">
<ComboboxVirtualizer>
…
</ComboboxVirtualizer>
</ComboboxViewport>
</ComboboxContent>
</ComboboxRoot>
</template>