記錄基於vue在我的真實項目中的性能優化

最近一段時間一直在處理公司的一個內部項目哈,因為頁面卡的問題被吐槽了一個月了。因為是接手別人的項目,雖然說不是自己直接造成的。但是解決這個問題已是迫在眉睫了。

可能我們在做前端開發的時候,很少去關注內存的問題,這是因為JS有自己垃圾回收機制,如果代碼不是濫用閉包,一般來說,不會出現性能問題。


記錄基於vue在我的真實項目中的性能優化

先來大概說下我的項目中性能瓶頸的現象:項目是一個基於electron+vue的一個類似微信桌面端的項目,因為是公司項目就不截圖了,想象是微信就行了。

當我們切換左側聯繫人列表的時候,發現內存不斷的上升,而且很難降下來,很典型的內存洩露了。

時間一長,內存吃完了,程序直接崩了。。。

好吧,解決問題吧,知道有內存洩露,我們一般會找項目中的代碼是不是有沒有及時釋放的閉包局部變量。

但是,效果不明顯。

我的解決方案

1、查看當前頁面的dom節點數。

一般來說在3000左右是為正常吧。這個如果查看呢?

很簡單,我們只需要在瀏覽器控制檯輸入:

$$("*")

即可!


記錄基於vue在我的真實項目中的性能優化

當我在我的項目中輸入的時候,節點達到了10000+了,好傢伙,問題找到了,原來是dom渲染太多了?

這應該是一個瓶頸吧,接下來不是去掉多餘的dom了,我發現在渲染列表的時候,一些很多的原點是沒有必要時時渲染的,還有一些dom是通過v-show來隱藏起來的。

慢慢的把這些問題解決了,dom節點降下來了。內存是得到了很好的控制。

你們以為這就完了嗎?

但是隨著列表的切換,內存還是會上升,只是沒那麼明顯了。

What??

你們說氣人不?沒辦法,還得繼續優化了。

這時候,我們要結合我的第一種方案,形成第二種方案。

2、優化渲染列表本身。

一般來說,我們列表的數據是通過後端或者本地數據庫獲取到的一個數組對象,而數組的每一項一般都是一個Json對象。我們是直接將這個數據對象掛載到組件的data對象或者vuex中去。

不管是哪種方案,在讀過vue源碼後,知道他是存在一問題的。

首先,我們的組件的data對象下數據,vue為了雙向數據綁定,會給每一個屬性添加get和set函數。也就是說。一個數據對象所有的屬性都會添加一次get和set,但是如果說我們的列表中的數據不需要數據響應,那這個get和set是沒有意義的。

好了,有這個思路,我們應該要想辦法不讓vue去給這個列表數據添加get和set。那該怎麼做呢?

要麼說閱讀源碼很重要呢?因為我之前看過數據響應的相關源碼哈,我就直接帶大家看一眼吧。


記錄基於vue在我的真實項目中的性能優化


在defineReactive方法中,它是專門用來定義get和set的,我們可以看到有一個情況他是不進行get和set的,當對象的configable為false的時候。

一般來說,一個對象的configurable屬性為false的時候。

好像看到希望了

在ES5中,Object對象下有一個方法可以!!!

Object.freeze ,它可以將一個對象凍結起來。


記錄基於vue在我的真實項目中的性能優化

當我們用Object.freeze將對象凍結的時候,我們再來看效果


記錄基於vue在我的真實項目中的性能優化

結果一目瞭然了吧。

好了,接下來我們將我們要渲染的列表用Object.freeze來凍結。再來看效果。

果不其然,內存下來了,正常了。。。哈哈哈


問題來了,當我們把對象凍結後,如果我們想去修改數組中的某一項的數據的時候,這時候我們是無法直接修改的。這時候,我們需要先將凍結後的數組拿到,然後通過[...list];進行解凍。然後修改,然後將新的數組重新凍結再去更新data或者 vuex! 完美解決。


記錄基於vue在我的真實項目中的性能優化

技術總結:

在排查問題的同時,我先考慮了本地數據庫的性能問題,排除後再去排查ui的問題。

我們在vue項目開發的時候,一定要注意我們看不到的頁面不要渲染無效的dom結構,要想提高列表的渲染性能,Object.freeze能大大幫助們提高頁面性能。

從排查問題,到解決問題,過程是痛苦的,但是當問題被解決的時候,被用戶肯定的時候,這些都值了。。

如果大家還有其它更好的優化方案,評論區告訴我下啊。

這裡是暢哥聊技術,歡迎關注,堅持將自己的一線開發經驗形成技術文章,希望能幫助到大家。

全文完!


分享到:


相關文章: