中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS如何解決內存泄漏頁面崩潰問題

發布時間:2022-08-17 09:44:19 來源:億速云 閱讀:441 作者:iii 欄目:開發技術

這篇“JS如何解決內存泄漏頁面崩潰問題”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“JS如何解決內存泄漏頁面崩潰問題”文章吧。

死去的頁面突然攻擊我?

因為項目本身過于龐大,且用戶反饋不特定頁面崩潰,這使得問題定位難度較大。

經過團隊的討論認為可能是該用戶的組織架構接口數據量過大,當數據到達頁面后需要經過遞歸處理,導致內存不足,且通過調試發現并非初次調用該接口就會導致崩潰,而是需要多次調用才會出現該問題。

而且在調試的過程中還發現因數據量過大,該接口需要長達 30s 的時間才能返回。而這么長的時間用戶可能已經離開這個頁面了。我們嘗試以這個場景進行操作發現,用戶離開頁面并沒有取消已經發出的請求,當該請求響應后會導致內存占用飆升。

因該接口為項目全局接口,經過討論我們決定先修復這個離開頁面不取消請求的問題,測試能否解決崩潰問題。

JS如何解決內存泄漏頁面崩潰問題

陷入僵局

當我們在離開頁面時取消未完成的請求后,測試反饋仍然會不定時崩潰,此時的我們有點無從下手了。因為我們發現問題貌似有點大了。

此時我們已經開始懷疑出現了內存泄漏,于是我們祭出了 chrome-devtool 使用 Memory 來進行內存占用分析。

JS如何解決內存泄漏頁面崩潰問題

經過內存分析發現,內存中存在大量的分離元素未能及時回收。我按照內存快照的指引開始了漫長的修改。兩天的修改后發現,雖然修復了不少的問題,但是仍然不能有效的降低頁面的內存占用,每當我們跳轉新的頁面時某些頁面仍然不能正常釋放。此時我為了高效定位問題,開始使用絕招——刪代碼。

  • 將頁面中的組織架構樹刪除——內存占用沒降下來...

  • 將頁面的列表刪除——很棒空頁面果真降下來了

  • 將組織架構樹加上,列表刪除——內存又起來了...

此時的我認為組織架構樹的寫法有問題,所以花了兩天的時間過了一遍組織架構樹的代碼,未發現有什么異常的地方。

為了確認是組織架構樹的問題還是頁面列表的問題,我在項目中新建了兩個空白的路由頁面。在這個頁面中單獨使用這兩個組件,都沒有問題。

問題陷入了僵局...

垂死病中驚坐起

在我們修復這個問題的期間,另一個用戶也反饋了相同的問題過來,不過用戶說他用的是edge瀏覽器。此時同事說edge好像可以撐的更久一點。????哇,真的嗎?難道和瀏覽器有關系?

于是我又打開了edge瀏覽器,點開了devtool點開了Memory...哎?這是什么

JS如何解決內存泄漏頁面崩潰問題

edge的devtool這么好嗎,專門有獨立的標簽用來查找分離的元素啊,蠻人性化的嘛。可是這和chrome不一樣呀,咋用呢?(戳這里)

JS如何解決內存泄漏頁面崩潰問題

它真的好智能,竟然已經把所有泄漏的dom按照結構組織好了,這樣就不用我再從一堆內存信息中一個個找它們的關聯關系了。

從上圖我發現原來是有一個全局的tip()方法導致了整個頁面沒能正常回收,用戶每進一次這個頁面就會在內存里多一份這個頁面的dom節點。而這個頁面又有完整的組織架構樹,組織架構樹又很大...

查看了tip()方法的源碼發現,這是一個全局的指令,這個指令每次都會創建一個新的tip對象,而這個tip對象與頁面上的dom節點關聯,且永遠不會被銷毀。

類似的問題在列表中有個對表格行拖拽排序的功能,使用了第三方包sortablejs而未調用destory()方法銷毀sortable 實例,進而導致表格與頁面也未能正確釋放。

勿以善小而不為

到此,大概的原因已經明確了。未及時銷毀的無用對象導致了大面積的內存泄漏,疊加用戶的配置較低(8G內存,且開啟了很多頁面),導致了頁面的崩潰。

類似以上的問題在本次修復中還發現不少,如:

  • 公共彈窗組件將傳入的子組件持有,在關閉彈窗后未能銷毀子組件。

  • 全局的EventBus實例未及時調用$off方法銷毀事件,而事件回調與頁面又產生關聯(如:$refs、$parents)

  • 組件接受來自頁面的方法,而該組件未能在頁面離開時銷毀(如在組件內將組件的this綁定在window上),導致整個頁面不能釋放

  • 為了在頁面resize時能夠調節echarts大小,在window上綁定了resize回調,離開頁面時為清除resize事件

  • 組件實例化時在document上綁定click事件后,銷毀組件時為清除click事件

以上的每一個問題都是小問題,僅僅是因為沒用在beforeDestroy中調用Element.removeEventListener()或者未調用destroy()方法。但是會導致很大的后患。

修復后的頁面已經能夠達到較為正常的內存占用了,在此給大家放一張測試同學提供的修復前后的內存占用對比圖,相較于修復前的內存占用只增不減(峰值4G,然后崩潰)到現在的能及時回收(最復雜的頁面峰值500M,普通頁面100M以內),已經有了極大的提升。

JS如何解決內存泄漏頁面崩潰問題

JS如何解決內存泄漏頁面崩潰問題

修改參考

const handleResizeWindow = () => {
    myChart.resize();
}
window.addEventListener("resize", handleResizeWindow);
this.$once('hook:beforeDestroy', () => {
    myChart.dispose() // 銷毀echart實例
    window.removeEventListener('resize', handleResizeWindow)
})
created () {
    window.removeEventListener('beforeunload', this.closePage)
},
...
beforeDestroy () {
    window.removeEventListener('beforeunload', this.closePage)
}
 mounted() {
     this.$eventBus.$on("eventName", this.handleEvent);
     this.$once('hook:beforeDestroy', () => {
         this.$eventBus.$off('eventName', this.handleEvent)
     })
 }

以上就是關于“JS如何解決內存泄漏頁面崩潰問題”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI

枣庄市| 象山县| 乾安县| 辛集市| 东源县| 利辛县| 淮南市| 扶沟县| 和硕县| 香河县| 奈曼旗| 昂仁县| 淮南市| 麻栗坡县| 林芝县| 长武县| 桐庐县| 弥勒县| 沁阳市| 寿光市| 无棣县| 西盟| 永胜县| 崇礼县| 宁远县| 儋州市| 盐城市| 绍兴市| 秭归县| 古浪县| 长子县| 普兰店市| 囊谦县| 牙克石市| 昌黎县| 三河市| 格尔木市| 全州县| 饶平县| 红原县| 卫辉市|