High-performance virtual scroll component supporting dynamic height rendering, optimized for large data list display
- 🚀 Efficient rendering of massive datasets
- 📏 Supports fixed height and dynamic height
- 🔍 Automatically calculates visible area content
- 🔄 Built-in scroll optimization and buffer mechanism
- ⏳ Smart loading state management
- 🔧 Highly customizable configuration
npm install @jason12306/vue-async-virtual-scroll
<template>
<div class="test-container">
<div class="scroll-container">
<async-virtual-scroll v-model="show" :data="items" :item-size="60">
<template v-slot="{ item, dataUid }">
<div class="list-item" :data-uid="dataUid" :style="{ backgroundColor: item.color }">
{{ item.id }}. {{ item.text }}
</div>
</template>
</async-virtual-scroll>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import AsyncVirtualScroll from '@jason12306/vue-async-virtual-scroll'
import '@jason12306/vue-async-virtual-scroll/vue-async-virtual-scroll.css'
const show = ref(false)
const num = 500
const items = ref([])
for (let i = 1; i <= num; i++) {
items.value.push({
id: i,
text: `Item ${i}`,
color: i % 2 ? '#e0f7fa' : '#fffde7',
})
}
onMounted(() => {
show.value = true
})
</script>
<style scoped>
.test-container {
padding: 20px;
}
.scroll-container {
height: 500px;
border: 1px solid #ddd;
overflow: auto;
}
.list-item {
height: 60px;
line-height: 60px;
padding: 0 16px;
border-bottom: 1px solid #eee;
box-sizing: border-box;
}
</style>
Name | Type | Required | Default | Description |
---|---|---|---|---|
v-model | Boolean | Yes | false | Controls whether virtual scrolling is enabled (must use v-model binding) |
ban | Boolean | No | false | Disable virtual scrolling (for small datasets) |
itemSize | Number | Required for fixed height | undefined | Item height in fixed-height mode (px) |
minItemSize | Number | Required for dynamic height | undefined | Minimum item height in dynamic-height mode (px) |
data | Array | Yes | [] | Data array to render |
buffer | Array | No | [200, 200] | Buffer zone sizes [top buffer, bottom buffer] (px) |
keyField | String | No | 'id' | Field name for unique identifier in data items |
dataUid | String | No | 'data-uid' | DOM attribute name for storing data unique identifier |
viewNum | Number | No | 1 | Minimum number of items visible initially (for estimation) |
Main rendering slot for defining each item's content
Parameter | Type | Description |
---|---|---|
item | Object | Current data item |
index | Number | Item index in data |
dataUid | String | Item unique identifier |
When all items have the same height, use fixed height mode for optimal performance:
<async-virtual-scroll v-model="enabled" :data="largeList" :item-size="60">
<!-- template content -->
</async-virtual-scroll>
When items have varying heights, use dynamic height mode:
<async-virtual-scroll v-model="enabled" :data="varyingHeightList" :min-item-size="40">
<!-- template content -->
</async-virtual-scroll>
Disable virtual scrolling for small datasets:
<async-virtual-scroll :data="list" :ban="list.length < 100">
<!-- template content -->
</async-virtual-scroll>
Adjust buffer sizes as needed:
<async-virtual-scroll :data="list" :buffer="[150, 300]">
<!-- template content -->
</async-virtual-scroll>
-
Must bind v-model
-
Dynamic Height Mode Requirements
- Must provide
minItemSize
property for initial height estimation - Component automatically detects and updates layout when item heights change
- Must provide
-
Performance Optimization Suggestions
- Prefer
itemSize
for fixed-height items - Set appropriate
buffer
values to balance performance and UX - Avoid complex computations in item templates
- Prefer
-
Data Updates
- Layout automatically updates when data changes
- Render area automatically adjusts for significant data changes
Traditional rendering methods create all DOM elements at once for large datasets, causing:
- High Memory Usage: Thousands of DOM nodes consume significant memory
- Reduced Rendering Performance: Browser handles excessive layout and paint operations
- Interaction Lag: Noticeable stuttering during scrolling and user interactions
Asynchronous Virtual Scrolling solves these issues by:
- 🚀 On-demand Rendering: Only renders elements in viewport
- ⏱ Deferred Calculation: Uses IntersectionObserver for async visibility detection
- 🔄 Smart Buffering: Preloads elements outside viewport for smooth scrolling
- 📊 Height Caching: Records rendered element heights to avoid recalculation
demo.mp4
MIT License