Render hàng nghìn DOM nodes cùng lúc rất chậm. Virtual scrolling chỉ render visible items:
Vue Virtual Scroller (@vueuse/components hoặc vue-virtual-scroller):
vue
<script setup>
import { useVirtualList } from '@vueuse/core'
const items = ref(Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })))
const { list, containerProps, wrapperProps } = useVirtualList(items, {
itemHeight: 40, // Fixed height per item (required)
})
</script>
<template>
<!-- Container với overflow scroll -->
<div v-bind="containerProps" style="height: 600px; overflow-y: auto">
<!-- Wrapper với total height để scroll bar đúng -->
<div v-bind="wrapperProps">
<!-- Chỉ visible items được render -->
<div
v-for="{ data: item } in list"
:key="item.id"
style="height: 40px"
>
{{ item.name }}
</div>
</div>
</div>
</template>Với variable-height items, dùng vue-virtual-scroller's DynamicScroller.
Kết hợp với v-memo cho items có nhiều reactive dependencies.