摘要:經過網上一翻查找,發現銷毀一個組件可以使用組件名來銷毀。本質上是把整個節點及對應的事件等都緩存下來了,當這樣的組件很多的時候,自然會占用很多內存。
問題產生的背景
我們一個后臺,在切換一些標簽頁的時候,是使用的 keep-alive 緩存的標簽頁,也使用了 include 屬性來決定哪個頁面進行緩存,而標簽頁的切換實際上是路由的切換,也就是說打開一個新標簽頁的時候,url 會跟著變化,老的標簽頁如果在 keep-alive 的 include 范圍內那就會緩存下來。
然后客服人員就反饋頁面開的久了就會崩潰,因為他們基礎上不會刷新頁面(工作需要),又總有切換標簽的習慣,最后導致內存越來越大最后崩潰。
這個項目是基于一個開源 vue 后臺框架:https://github.com/PanJiaChen/vue-element-admin,然后代碼一直由幾個后端開發維護的!所以后端沒找出問題在哪,然后就我來接手這個問題了。
寫文章時,標簽里竟然沒有 vue 這一項,差評!
先梳理下業務邏輯:從業務場景來說,我們在標簽頁之間切換時,如果剛進入的這個標簽頁已被緩存了,那被緩存的標簽頁就直接拿出來展示就行,而關閉這個標簽頁的時候就應該銷毀對應的組件。
花了點時間查看了一下代碼,發現問題在于關閉標簽頁的時候,雖然這個頁面沒在 keep-alive 的 include 里了,但是組件也沒有被銷毀掉,還是在緩存狀態,我們可以通過 Vue Devtools 插件看到關閉后的標簽頁對應的組件一直還存在著:
當然,在這塊 keep-alive 本身的邏輯我覺得是沒問題的,主要是我們項目比較復雜,緩存的組件太多了而且會一直增加,所以最終導致崩潰。
解決問題既然問題已經定位了,那就好解決問題了,只需要在關閉標簽頁的時候把對應的組件也銷毀掉就好了。
經過網上一翻查找,發現銷毀一個組件可以使用: this.$destroy(‘組件名’) 來銷毀。
先說下大概思路:keep-alive 的 include 里存的其實是一個 vuex 中的一個數據源(數據源保存的是路由名稱),當關閉標簽頁時,這個數據源中的一項會被移除。這之前,我們在組件里監聽到這個數據源的變化,如果此組件對應的路由(這個路由應在 mounted 的時候保存下來)已經不在數據源中了,那就應該銷毀此組件。
代碼大概如下:
const mixin = { data() { return { routePath: "" } }, mounted() { this.routePath = this.$route.path }, computed: { visitedViews() { return this.$store.state.tagsView.visitedViews } }, watch: { visitedViews(value) { if(value 里沒有了 routePath 這一項) this.$destroy(this.$options.name) } } } } export default mixin
這一段代碼多帶帶拎出來了,然后在需要緩存的組件里使用 mixins 混入到組件對象中,這樣組件中要添加的代碼量就比較少了。
更改后經過測試,關閉標簽頁后對應的組件就會被銷毀掉,使用 Vue Devtools 能看的很清楚。
更多思考在我們后臺操作這么頻繁的業務場景下,使用 keep-alive 其實并不是一個好的選擇。
在我們修復這個問題后,我們通過控制臺里的 Memory 查看頁面內存的變化時,發現組件即便被銷毀,也要經過一段時間才能回收完,當我們在這一段時間一直創建/打開新的標簽頁時,內存還是會在短時間內高漲。而且有時候,內存在經過一段時間后也并沒有回收掉。
keep-alive 本質上是把整個 dom 節點及對應的事件等都緩存下來了,當這樣的組件很多的時候,自然會占用很多內存。而如果我們只緩存這個組件中的數據,在需要這個組件再次顯示的時候再臨時渲染那肯定要節省很多內存的,畢竟數據占的空間其實很小的,而渲染組件要花的時間也不會很長(只要組件不是特別特別復雜)。
所以,下一階段的優化工作就是把 keep-alive 去掉,然后使用 vuex 來緩存組件中的數據,當需要重新顯示數據時再把數據取出來并重新渲染。當然,這是一個比較大的工程!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102739.html
摘要:文檔在及其更高版本中,和將會在樹內的所有嵌套組件中觸發。另外,在我們的項目中遇到路由相同但參數不同的情況組件被復用,不更新的問題,官方給出了響應路由參數變化根據參數數據響應 前言 在開發中經常有從列表跳到詳情頁,然后返回詳情頁的時候需要緩存列表頁的狀態(比如滾動位置信息),這個時候就需要保存狀態,要緩存狀態;vue里提供了keep-alive組件用來緩存狀態。可以用以下幾種方案解決問題...
摘要:很多優化點都是根據實際情況入手,上面這幾個,都是我在做項目時,感覺不合適而進行優化的,后面會持續補充下去 主要說的是,我在項目中,自己遇到的一些小問題和解決方案 圖片 base64 問題 // 有一個 test 的組件 .icon { background: url(../assets/test.png); } // 然后有三個頁面,引入了 test 組...
摘要:通過這兩種方式分別檢測是否匹配當前組件。修正取出中的不符合條件的,同時不是目前渲染的時,銷毀對應的組件實例實例,并從中移除銷毀對應的組件實例實例遍歷中的所有項,如果不符合指定的規則的話,則會執行。則會調用組件實例的方法來將組件銷毀。 keep-alive keep-alive是vue.js的內置組件,它能夠把不活動的組件的實例保存在內存中,而不是直接的銷毀,它是一個抽象組件,不會被渲染...
摘要:為的組件將不會被緩存。通過這兩種方式分別檢測是否匹配當前組件。修正取出中的不符合條件的,同時不是目前渲染的時,銷毀對應的組件實例實例,并從中移除銷毀對應的組件實例實例遍歷中的所有項,如果不符合指定的規則的話,則會執行。 寫在前面 因為對Vue.js很感興趣,而且平時工作的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,并做了總結與輸出。 文章的原地址:http...
摘要:實現動態緩存以及緩存銷毀需求來源及描述后臺管理系統中,左側為功能菜單欄,點擊菜單列表,右側顯示該菜單的功能頁面,本來是一個非常簡單的后臺管理系統布局,現在增加了菜單按鈕點擊左側菜單欄時,右側頁面頭部顯示當前的頁面標題,形成一個列表,點擊可 vue keep-alive實現動態緩存以及緩存銷毀 需求來源及描述 后臺管理系統中,左側為功能菜單欄,點擊菜單列表,右側顯示該菜單的功能頁面,本來...
閱讀 2473·2021-11-24 09:39
閱讀 3406·2021-11-15 11:37
閱讀 2251·2021-10-08 10:04
閱讀 3965·2021-09-09 11:54
閱讀 1883·2021-08-18 10:24
閱讀 1033·2019-08-30 11:02
閱讀 1793·2019-08-29 18:45
閱讀 1651·2019-08-29 16:33