Vue3實現(xiàn)高性能虛擬列表的兩種方法
正文
在前端開發(fā)中,大數(shù)據(jù)量列表渲染 一直是性能挑戰(zhàn)。假設(shè)我們有一個 API 返回 1 萬條數(shù)據(jù),如果直接渲染到頁面,必然會導(dǎo)致嚴重卡頓甚至瀏覽器崩潰。
解決方案就是 —— 虛擬列表 (Virtual List) 。
虛擬列表的核心思想是:只渲染當前視口范圍內(nèi)的元素,通過計算位置來“假裝”完整渲染。
常見實現(xiàn)方式主要有兩種:
- Spacer 占位法
- Absolute 定位法
本文將對比這兩種實現(xiàn),并給出適用場景。
1. Spacer 占位法實現(xiàn)
思路:用 上空白塊 + 下空白塊 撐出容器總高度,視口中只渲染真實元素。
<div ref="root" @scroll="onScroll"
:style="{ overflowY: 'auto', height: containerHeight + 'px' }">
<!-- 上占位 -->
<div :style="{ height: topSpacer + 'px' }"></div>
<!-- 可見元素 -->
<div v-for="item in visibleItems" :key="item.id" class="virtual-item">
{{ item.text }}
</div>
<!-- 下占位 -->
<div :style="{ height: bottomSpacer + 'px' }"></div>
</div>
優(yōu)點:
- 實現(xiàn)簡單直觀
- 支持動態(tài)高度(只要調(diào)整 spacer 值即可)
缺點:
- 多余的 DOM(兩個 spacer)
- 每次滾動都要更新
topSpacer和bottomSpacer,涉及 回流 (Reflow)
2. Absolute 定位法實現(xiàn)
思路:先撐出一個 固定高度的容器,每個 item 通過 absolute + top 定位。
<div ref="root" @scroll="onScroll"
:style="{ overflowY: 'auto', height: containerHeight + 'px', position: 'relative' }">
<!-- 總高度容器 -->
<div :style="{ height: totalHeight + 'px', position: 'relative' }">
<div v-for="(item, idx) in visibleItems"
:key="item.id"
class="virtual-item"
:style="{ position: 'absolute', top: (startIndex + idx) * itemHeight + 'px' }">
{{ item.text }}
</div>
</div>
</div>
優(yōu)點:
- DOM 結(jié)構(gòu)更簡潔(沒有 spacer)
- 絕對定位減少回流,性能更好
- 更適合大數(shù)據(jù)場景(5w+ 條時依然穩(wěn)定)
缺點:
- 對自適應(yīng)高度支持不友好(必須固定高度)
position: sticky等布局特性會失效
3. 性能對比
| 對比維度 | Spacer 占位法 | Absolute 定位法 |
|---|---|---|
| DOM 結(jié)構(gòu) | 多 2 個占位元素 | 更簡潔 |
| 回流影響 | spacer 高度頻繁變化,可能觸發(fā)回流 | 元素絕對定位,回流更少 |
| 動態(tài)高度 | 支持,容易實現(xiàn) | 支持困難,需要累積高度映射 |
| 大數(shù)據(jù)量 (10w+) | 可能浮點誤差 | 更穩(wěn),F(xiàn)PS 更高 |
| 布局特性 | 流式布局更自然 | 絕對定位可能受限 |
4. 實踐建議
- 固定高度 item → 推薦 Absolute 定位法
簡潔高效,減少 DOM & 回流開銷。 - 動態(tài)高度 item → 推薦 Spacer 占位法
更容易適配復(fù)雜布局。 - 超大數(shù)據(jù)量 (5w+ 條) → Absolute 更穩(wěn)
如果你要做一個通用組件,可以支持 兩種實現(xiàn)方式切換:
- 默認使用 Absolute 定位法
- 如果檢測到 item 高度不一致,再切換到 Spacer 占位法
這種混合策略,正是一些成熟虛擬列表庫(如 react-window、vue-virtual-scroll-list)的做法。
5. 結(jié)論
- 兩種方案都能解決虛擬列表問題
- Absolute 定位法 在固定高度場景下性能更優(yōu)
- Spacer 占位法 更靈活,能支持動態(tài)高度
所以,選擇哪種方案要根據(jù) 業(yè)務(wù)需求 來定。
到此這篇關(guān)于Vue3實現(xiàn)高性能虛擬列表的兩種方法的文章就介紹到這了,更多相關(guān)Vue3高性能虛擬列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue獲取token實現(xiàn)token登錄的示例代碼
最近新做了個vue項目,正好項目中有登錄部分,本文就詳細的介紹一下登錄部分的實現(xiàn),文中通過示例代碼介紹的非常詳細,感興趣的小伙伴們可以參考一下2021-11-11
vue+element?UI?文字加下劃線長度多出一點點的問題
這篇文章主要介紹了vue+element?UI?文字加下劃線長度多出一點點的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
element?table數(shù)據(jù)量太大導(dǎo)致網(wǎng)頁卡死崩潰的解決辦法
當頁面數(shù)據(jù)過多,前端渲染大量的DOM時,會造成頁面卡死問題,下面這篇文章主要給大家介紹了關(guān)于element?table數(shù)據(jù)量太大導(dǎo)致網(wǎng)頁卡死崩潰的解決辦法,需要的朋友可以參考下2023-02-02
vue+element實現(xiàn)動態(tài)換膚的示例代碼
本文主要介紹了vue+element實現(xiàn)動態(tài)換膚的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09

