vue渲染大量數(shù)據(jù)時卡頓卡死解決方法
1. 問題描述
由于業(yè)務(wù)需求,需要在一個頁面中點擊查詢按鈕時加載出所有的數(shù)據(jù),但數(shù)據(jù)量有近10萬條,渲染出現(xiàn)卡頓,頁面卡死。
2. 常見的解決方案
- 自定義中間層
自定義nodejs中間層,獲取并拆分這10w條數(shù)據(jù),
前端對接nodejs中間層,而不是服務(wù)器
缺點:成本高
- 虛擬列表
只渲染可視區(qū)域DOM,其他隱藏區(qū)域不顯示,只用div撐起高度,隨著瀏覽器滾動,創(chuàng)建和銷毀DOM。

虛擬列表實現(xiàn)起來非常復(fù)雜,可借用第三方lib
Vue-virtual-scroll-list
React-virtualiszed
- 前后端配合(本問題解決方案)
前端使用pl-table加載數(shù)據(jù);pl-table(大數(shù)據(jù)表格,完美解決萬級數(shù)據(jù)渲染卡頓問題)
后端循環(huán)獲取數(shù)據(jù),每次只獲取幾百條數(shù)據(jù),獲取后就進行渲染。
3. 解決方案流程圖
使用pl-table + 每次從后端讀取500條數(shù)據(jù)后就渲染 ,渲染完成后如果還有數(shù)據(jù)繼續(xù)獲取數(shù)據(jù)500條并渲染,直至數(shù)據(jù)讀取完成。
流程圖如下圖所示:

1)點擊查詢按鈕
2)判斷是否正在查詢(isSearching)
3)isSearching = true ;正在查詢時判斷是否需要停止,需要停止則查詢結(jié)束;不需要停止則繼續(xù)查詢過程(不需要額外操作)。
4)isSearching = false ;沒有正在查詢,這時需要設(shè)置 isSearching = true;startId = 0 (查詢的開始id);
searchingTaskTag = genUuid()// 隨機數(shù)(用來在前后端傳遞,保證是同一個查詢)
5)調(diào)用中間fn1函數(shù),判斷當(dāng)前請求數(shù)據(jù)的最大Id是否小于等于0,如果小于等于0 則請求出最大maxId,并設(shè)置endId = startId + step(查詢的結(jié)束Id);
6) 判斷startId <= maxId 為true,則調(diào)用函數(shù)fn2,隨機數(shù)searchingTaskTag請求和響應(yīng)中攜帶。
7)根據(jù)response.searchingTaskTag === searchingTaskTag 判斷是否是同一個請求,如果是數(shù)據(jù)則累加進去,同時 startId = startId + step;并去調(diào)用步驟5)。
8)判斷startId <= maxId 為false,則結(jié)束查詢。
4. 代碼
查詢方法
//查詢
handleSearch() {
//this.isShow = false;
if (this.isSearching) {
// 提示用戶是否停止查詢?
this.$confirm("確認(rèn)停止查詢?", "提示", {
type: "warning",
}).then(() => {
this.listLoading = false;
this.searchingTaskTag = "";
this.isSearching = false;
this.hardReset = false;
this.$nextTick(() => {
this.hardReset = true;
});
});
} else {
this.isSearching = true;
this.searchingTaskTag = genUuid();
this.tableData = [];
this.startId = 0;
this.fn1();
}
},
中間函數(shù)fn1
async fn1() {
let startId = this.startId;
let endId = this.startId + this.step;
let param = {
pageNo: this.page,
pageSize: this.pageSize,
startId: startId,
endId: endId,
searchingTaskTag: this.searchingTaskTag,
};
try {
if (this.maxId <= 0) {
let response = await getMaxId();
this.maxId = response.body;
}
if (startId <= this.maxId) {
this.fn2(param);
} else {
this.$message.success("查詢結(jié)束!");
this.isSearching = false;
}
} catch (e) {}
},
getMaxId() {
getMaxId()
.then((resp) => {
this.maxId = resp.body;
})
.catch((error) => {
this.$message.error(error.body);
});
},fn2 函數(shù)
//獲取數(shù)據(jù)列表
fn2(param) {
fn2(param).then(
(resp) => {
let tempList = resp.body.content;
let echoSearchingTaskTag = resp.body.searchingTaskTag;
if (
tempList.length > 0 &&
this.searchingTaskTag == echoSearchingTaskTag
) {
this.tableData.push(...tempList);
}
if (this.searchingTaskTag == echoSearchingTaskTag) {
this.listLoading = false;
this.startId += this.step;
this.fn1();
}
})
.catch((error) => {
this.listLoading = false;
this.$message.error("獲取失敗!");
this.isSearching = false;
this.flag = false;
});
this.listLoading = false;
},
到此這篇關(guān)于vue渲染大量數(shù)據(jù)時卡頓卡死解決方法的文章就介紹到這了,更多相關(guān)vue渲染數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
讓FireFox支持innerText的實現(xiàn)代碼
DHTML非標(biāo)準(zhǔn)屬性innerText在FireFox中的使用2009-12-12
200行代碼實現(xiàn)blockchain 區(qū)塊鏈實例詳解
這篇文章主要介紹了200行代碼實現(xiàn)blockchain 區(qū)塊鏈的相關(guān)知識,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2018-03-03
使用JavaScript實現(xiàn)響應(yīng)式計數(shù)器動畫
在本文中,我們將學(xué)習(xí)如何使用?HTML?CSS?和?JavaScript創(chuàng)建響應(yīng)式計數(shù)器動畫。?我們在很多地方都可以用,比如適用于不同類型的個人網(wǎng)站、企業(yè)網(wǎng)站等,感興趣的可以了解一下2022-08-08
javascript實現(xiàn)在下拉列表中顯示多級樹形菜單的方法
這篇文章主要介紹了javascript實現(xiàn)在下拉列表中顯示多級樹形菜單的方法,涉及javascript屬性菜單的定義、構(gòu)造及遍歷等技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08
JavaScript實現(xiàn)網(wǎng)頁版貪吃蛇游戲
這篇文章主要為大家詳細(xì)介紹了JavaScript實現(xiàn)網(wǎng)頁版貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07

