When rendering hundreds or thousands of items, Vue 3 apps can lag noticeably. We hit this problem in a recent inventory management system — 5,000 items caused 3-second load times and scrolling dropped below 15fps.
Here are 5 solutions we tested, ranked by effectiveness.
1. Virtual Scrolling (Best Overall)
Only render DOM elements within the visible viewport. We recommend vue-virtual-scroller:
<RecycleScroller :items="list" :item-size="60" key-field="id">
<template #default="{ item }">
<div class="item">{{ item.name }}</div>
</template>
</RecycleScroller>
Result: Initial render dropped from 3.2s to 0.1s. Memory from 180MB to 35MB.
2. Pagination + Infinite Scroll
Use the Intersection Observer API for load-on-scroll, fetching 20-50 items per request. Best when total data volume is unknown.
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) loadMore()
})
observer.observe(sentinel)
3. v-memo Directive
Vue 3.2+'s v-memo caches subtree render results, skipping re-renders when dependent data hasn't changed:
<div v-for="item in list" :key="item.id" v-memo="[item.name, item.price]">
<ExpensiveComponent :data="item" />
</div>
Great for lists where individual items rarely change.
4. Web Worker Off-Thread Computing
Move computation-intensive operations like filtering and sorting to Web Workers:
const worker = new Worker('./listWorker.js')
worker.postMessage({ action: 'filter', data: rawList, query })
worker.onmessage = e => { filteredList.value = e.data }
This prevents main thread blocking during heavy operations.
5. shallowRef + triggerRef
For large lists that don't need deep reactivity:
const list = shallowRef(hugeArray)
// After mutation:
triggerRef(list)
Avoids Vue creating deep proxies for every element — significant memory savings.
Benchmark Summary
| Solution | Render Time (5K items) | Memory |
|---|---|---|
| Default v-for | 3.2s | 180MB |
| Virtual Scrolling | 0.1s | 35MB |
| v-memo | 1.8s | 160MB |
| shallowRef | 2.1s | 90MB |
Our recommendation: Virtual scrolling first, pagination second. They solve the root cause (too many DOM nodes) rather than optimizing around it.
Small team, big output. iDev builds web apps, AI solutions and custom systems with startup speed and enterprise quality. Based in Malaysia, serving Southeast Asia. Free consultation.
Top comments (0)