Vue3組合式API中如何優(yōu)化列表渲染性能
1.響應(yīng)式數(shù)據(jù)優(yōu)化
避免不必要的響應(yīng)式轉(zhuǎn)換
在使用v - for進(jìn)行列表渲染時(shí),對(duì)于不會(huì)發(fā)生變化的數(shù)據(jù),盡量避免將其轉(zhuǎn)換為響應(yīng)式數(shù)據(jù)。例如,如果列表中的元素包含一些靜態(tài)屬性(如固定的標(biāo)簽、不會(huì)改變的描述等),可以將這些屬性放在非響應(yīng)式對(duì)象中,而只將需要?jiǎng)討B(tài)更新的關(guān)鍵屬性(如用戶狀態(tài)、數(shù)據(jù)值等)使用ref或reactive進(jìn)行響應(yīng)式包裝。
假設(shè)我們有一個(gè)用戶列表,其中用戶的姓名是固定的,而用戶的在線狀態(tài)是會(huì)變化的:
<template> <ul> <li v - for="user in userList"> {{ user.name }} - <span :class="{ online: user.isOnline }">Status: {{ user.isOnline? 'Online' : 'Offline' }}</span> </li> </ul> </template> <script setup> import { reactive } from 'vue'; const userList = reactive([ { name: 'Alice', isOnline: ref(true) }, { name: 'Bob', isOnline: ref(false) } ]); </script>
在這里,`user.name`是固定的,不需要響應(yīng)式處理,而`user.isOnline`是使用`ref`進(jìn)行響應(yīng)式包裝的,這樣可以減少不必要的響應(yīng)式開銷。
精準(zhǔn)更新響應(yīng)式數(shù)據(jù)
當(dāng)更新列表中的部分?jǐn)?shù)據(jù)時(shí),盡量精準(zhǔn)地更新響應(yīng)式數(shù)據(jù),避免重新渲染整個(gè)列表。例如,如果只是修改了列表中某個(gè)元素的一個(gè)屬性,應(yīng)該直接更新該屬性,而不是重新賦值整個(gè)元素。
比如,要更新用戶列表中某個(gè)用戶的在線狀態(tài):
<script setup> import { reactive } from 'vue'; const userList = reactive([ { name: 'Alice', isOnline: ref(true) }, { name: 'Bob', isOnline: ref(false) } ]); const updateUserStatus = (index, newStatus) => { userList[index].isOnline.value = newStatus; }; </script> <template> <ul> <li v - for="(user, index) in userList"> {{ user.name }} - <span :class="{ online: user.isOnline }">Status: {{ user.isOnline? 'Online' : 'Offline' }}</span> <button @click="updateUserStatus(index, true)">Set Online</button> <button @click="updateUserStatus(index, false)">Set Offline</button> </li> </ul> </template>
通過(guò)直接更新`userList[index].isOnline.value`,Vue能夠更精準(zhǔn)地更新DOM,只重新渲染受影響的部分,而不是整個(gè)列表。
2.虛擬DOM和Diff算法優(yōu)化
使用key屬性
在v - for指令中,為每個(gè)列表項(xiàng)提供一個(gè)唯一的key屬性是非常重要的。key屬性幫助Vue識(shí)別每個(gè)列表項(xiàng),使得在更新列表時(shí),Vue能夠更高效地通過(guò)虛擬DOM的Diff算法來(lái)比較新舊列表,只重新渲染必要的部分。
例如,在渲染用戶列表時(shí):
<template> <ul> <li v - for="user in userList" :key="user.id"> {{ user.name }} - <span :class="{ online: user.isOnline }">Status: {{ user.isOnline? 'Online' : 'Offline' }}</span> </li> </ul> </template> <script setup> import { reactive } from 'vue'; const userList = reactive([ { id: 1, name: 'Alice', isOnline: ref(true) }, { id: 2, name: 'Bob', isOnline: ref(false) } ]); </script>
這里使用`user.id`作為`key`屬性,當(dāng)列表的順序發(fā)生變化或者添加、刪除部分元素時(shí),Vue可以根據(jù)`key`快速定位到變化的元素,提高更新效率。
理解Diff算法的工作原理
Vue的虛擬DOM Diff算法會(huì)比較新舊虛擬DOM樹的節(jié)點(diǎn)。當(dāng)進(jìn)行列表渲染時(shí),它會(huì)根據(jù)key屬性來(lái)匹配新舊節(jié)點(diǎn)。如果節(jié)點(diǎn)的key相同,會(huì)進(jìn)一步比較節(jié)點(diǎn)的其他屬性是否變化;如果key不同,會(huì)認(rèn)為是新的節(jié)點(diǎn)插入或者舊的節(jié)點(diǎn)刪除。
例如,當(dāng)在列表中插入一個(gè)新用戶時(shí),Diff算法會(huì)根據(jù)新用戶的key(假設(shè)id作為key)來(lái)判斷是在哪個(gè)位置插入新節(jié)點(diǎn),并且只會(huì)更新插入位置之后受影響的節(jié)點(diǎn)的DOM,而不是重新渲染整個(gè)列表。
3.組件化和懶加載優(yōu)化
組件化列表項(xiàng)
如果列表中的每個(gè)元素都比較復(fù)雜,包含大量的邏輯和DOM結(jié)構(gòu),可以將列表項(xiàng)封裝成一個(gè)單獨(dú)的組件。這樣,在更新列表時(shí),Vue可以更高效地管理每個(gè)組件的更新,并且可以利用組件的生命周期鉤子來(lái)優(yōu)化性能。
例如,將用戶列表項(xiàng)封裝成一個(gè)UserListItem組件:
<template> <li> {{ user.name }} - <span :class="{ online: user.isOnline }">Status: {{ user.isOnline? 'Online' : 'Offline' }}</span> </li> </template> <script setup> import { defineProps } from 'vue'; const props = defineProps({ user: Object }); </script>
然后在父組件中使用`v - for`來(lái)渲染這個(gè)組件:
<template> <ul> <UserListItem v - for="user in userList" :user="user" :key="user.id"/> </ul> </template> <script setup> import { reactive } from 'vue'; import UserListItem from './UserListItem.vue'; const userList = reactive([ { id: 1, name: 'Alice', isOnline: ref(true) }, { id: 2, name: 'Bob', isOnline: ref(false) } ]); </script>
懶加載列表項(xiàng)組件
對(duì)于包含大量列表項(xiàng)的長(zhǎng)列表,考慮使用懶加載技術(shù)。即只有當(dāng)列表項(xiàng)進(jìn)入可視區(qū)域時(shí)才加載組件??梢允褂靡恍┑谌綆?kù)(如vue - lazyload)或者瀏覽器的Intersection Observer API來(lái)實(shí)現(xiàn)。這樣可以減少初始加載時(shí)的性能開銷,特別是在移動(dòng)設(shè)備或者網(wǎng)絡(luò)較慢的環(huán)境下。
以上就是Vue3組合式API中如何優(yōu)化列表渲染性能的詳細(xì)內(nèi)容,更多關(guān)于Vue3列表渲染性能優(yōu)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
nuxt實(shí)現(xiàn)封裝axios并且獲取token
這篇文章主要介紹了nuxt實(shí)現(xiàn)封裝axios并且獲取token,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue項(xiàng)目打包優(yōu)化的方法實(shí)戰(zhàn)記錄
最近入職了新公司,接手了一個(gè)新拆分出來(lái)的Vue項(xiàng)目,針對(duì)該項(xiàng)目做了個(gè)打包優(yōu)化,把經(jīng)驗(yàn)分享出來(lái),下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目打包優(yōu)化的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08Vue數(shù)據(jù)驅(qū)動(dòng)模擬實(shí)現(xiàn)2
這篇文章主要介紹了Vue數(shù)據(jù)驅(qū)動(dòng)模擬實(shí)現(xiàn)的相關(guān)資料,實(shí)現(xiàn)Observer構(gòu)造函數(shù),監(jiān)聽已有數(shù)據(jù)data中的所有屬性,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01Vue?Echarts實(shí)現(xiàn)多功能圖表繪制的示例詳解
作為前端人員,日常圖表、報(bào)表、地圖的接觸可謂相當(dāng)頻繁,今天小編隆重退出前端框架之VUE結(jié)合百度echart實(shí)現(xiàn)中國(guó)地圖+各種圖表的展示與使用;作為“你值得擁有”專欄階段性末篇,值得一看2023-02-02如何在 ant 的table中實(shí)現(xiàn)圖片的渲染操作
這篇文章主要介紹了如何在 ant 的table中實(shí)現(xiàn)圖片的渲染操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10Vue0.1的過(guò)濾代碼如何添加到Vue2.0直接使用
Vue0.1的過(guò)濾代碼如何添加到Vue2.0直接使用,這篇文章主要介紹了過(guò)濾代碼添加到Vue2.0用的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Vite打包項(xiàng)目后圖片丟失的簡(jiǎn)單解決方法
vue項(xiàng)目完成打包上線的時(shí)候很多人都會(huì)碰到靜態(tài)資源找不到的情況,下面這篇文章主要給大家介紹了關(guān)于Vite打包項(xiàng)目后圖片丟失的簡(jiǎn)單解決方法,需要的朋友可以參考下2023-05-05詳解vue-router的導(dǎo)航鉤子(導(dǎo)航守衛(wèi))
這篇文章主要介紹了詳解vue-router的導(dǎo)航鉤子(導(dǎo)航守衛(wèi)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11