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