用戶自己制造了性能問題,還怪我前端沒做優(yōu)化?
相信大家都有做過這類的后臺管理系統(tǒng)。
圖片
我們團(tuán)隊(duì)也有類似于這樣的后臺管理系統(tǒng)平臺,且當(dāng)用戶切換到某一個(gè)頁面時(shí),這個(gè)頁面都得去請求最新的數(shù)據(jù),呈現(xiàn)出來~
這就會造成一個(gè)問題:當(dāng)用戶頻繁切換 Tab 切換的時(shí)候,就會不斷地去發(fā)起請求,進(jìn)行渲染呈現(xiàn),但是其實(shí)正在有意義的只有用戶最后一次切換到的頁面,我服了,真有人會這么頻繁切換嗎?不會是用戶自己切著玩吧?
圖片
那應(yīng)該怎么去優(yōu)化呢?很多人第一時(shí)間想到了防抖,但是我想說的是:一般的防抖還真防不住!
一般的防抖
如果是比較普通的場景還是可以用用一般防抖的,就比如某一個(gè)頁面內(nèi)的 Tab 切換,因?yàn)檫@一類的 Tab 切換說到底就是在同一個(gè)頁面組件下去寫代碼邏輯,所以也比較好控制這些 Tab 切換后的防抖處理
圖片
我們用一個(gè)小案例來演練一下,我準(zhǔn)備四個(gè)文件,Index.vue、Tab1.vue、Tab2.vue、Tab3.vue
Tab1.vue
圖片
Tab2.vue
圖片
Tab3.vue
圖片
Index.vue
圖片
我們只需要在 Index.vue 中監(jiān)聽 Tab 的切換,然后獲取對應(yīng)的組件實(shí)例,去執(zhí)行它們的 init 方法,就可以做到每次切換 Tab 都能去請求獲取最新的數(shù)據(jù)
有人會問為啥不能直接將每個(gè)組件中的 init 寫在各自的 onMounted 中?我來回答一下吧,因?yàn)?nbsp;Tab 默認(rèn)會做頁面緩存,也就是只有第一次切換過去才會執(zhí)行 onMounted,往后都不會執(zhí)行了,這樣有助于提升性能,所以不能將 init 寫在 onMounted 中~
現(xiàn)在我們切換 Tab,會發(fā)現(xiàn)每切換一次就去運(yùn)行請求一次,這顯然違背了我們的期望
圖片
所以我們可以直接給 onTabChange加上防抖,即可解決此問題。
圖片
現(xiàn)在我同樣是頻繁切換,但是最終發(fā)起請求的只有一次,也就是用戶最終跳轉(zhuǎn)到的 Tab。
圖片
這就是一般的防抖的應(yīng)用場景。
進(jìn)階版防抖
上面所說的一般的防抖只能適用于代碼邏輯相對于比較集中的場景。
但是如果是那種代碼邏輯比較分散的場景呢?比如后臺管理系統(tǒng)中,通過切換不同的 Tab 去切換不同的 路由頁面,且這些頁面都是經(jīng)過 keep-alive 處理過的,且每個(gè)頁面的請求邏輯都放在 onMounted 中。
圖片
這些頁面都是一個(gè)個(gè)的文件夾管理的,代碼邏輯相對比較分散。
為了簡化場景,降低大家的閱讀成本,我還是用剛剛的代碼來模擬,還是 Index.vue、Tab1.vue、Tab2.vue、Tab3.vue。
Tab1.vue
圖片
Tab2.vue
圖片
Tab3.vue
圖片
Index.vue
圖片
我們切換 Tab 時(shí),可以發(fā)現(xiàn)每個(gè) Tab 的請求只會發(fā)起一次,因?yàn)?nbsp;onMounted 只會執(zhí)行一次
圖片
但是我們想要的是每次切換 Tab 之后,每個(gè)頁面都要去重新發(fā)起請求,那應(yīng)該怎么做呢?
其實(shí)很簡單,我們只需要 “改造” 一下 onMounted 即可
我們新建一個(gè)useCustomMounted.ts ,使用 watch + nextTick 來取代 onMounted
圖片
接著在Tab1.vue、Tab2.vue、Tab3.vue 中去使用這個(gè) onCustomMounted,這里我只貼出 Tab1.vue 的,其他兩個(gè) Tab 同理,我就不貼出來了
圖片
接著在 Index.vue 中需要去監(jiān)聽 Tab 變化,并觸發(fā) changeActiveKey
圖片
現(xiàn)在切換 Tab 時(shí),每次都會觸發(fā)請求的起了。
圖片
接下來就要加上防抖了,只需要加在 changeActiveKey 上即可。
圖片
現(xiàn)在我同樣是頻繁切換,但是最終發(fā)起請求的只有一次,也就是用戶最終跳轉(zhuǎn)到的 Tab