淺談web應用的內存優化

隨着 Web 應用複雜程度愈來愈高,以及 NodeJS 大規模投入生產環境,許多 Web 應用都會長時間運行, JavaScript 的內存管理顯得更爲重要。前端

JavaScript 具有自動回收垃圾的機制, 執行環境會負責管理代碼在執行環境過程當中使用的內存,將某些再也不被使用的的變量所佔用的內存釋放掉,正因如此,大多數狀況咱們在前端開發的時候,並非那麼關注咱們的頁面用了多少內存,是否合理,需不須要優化。node

JavaScript 基礎中有不少重要的知識點是和內存相關的,好比深拷貝和淺拷貝、閉包、原型、引用數據類型和引用傳遞等。設計模式

固然,關於 JS 的內存空間和內存相關的知識已經有不少專業的文章解釋的很詳細了,這裏就再也不贅述了。瀏覽器

好比關於 JS 內存空間的知識能夠看看:內存空間詳細圖解緩存

關於內存週期和垃圾回收的知識能夠閱讀參考 MDN 的文章,其餘文章無外乎也是根據這個來介紹的:Memory_Managementbash

關於 JavaScript 內存泄漏也能夠看一下阮一峯老師的文章 JavaScript 內存泄漏教程閉包

在 Web 應用開發中,咱們應該注意:函數

1. 避免沒有必要全局變量的使用
前端開發者都知道,在局部做用域中,當函數執行完畢,局部變量也就沒有存在的必要了,它很容易被垃圾回收器回收,當使用全局變量定義值時,垃圾回收器,很難判斷全局變量須要何時釋放內存空間,所以是不會去對其進行回收銷燬的。而該變量會一直存在老生代堆內存中,直到頁面被關閉。大數據

function setName () {
     name = "alloy";
}
 
// 等價
 
function setName () {
        window.name = "alloy"
}
複製代碼

另一種意外狀況是;優化

function setName (name) {
    this.name = name;
}
 
setName("alloy");
複製代碼

咱們能夠在 JS 文件的開頭經過添加"use strict" 開啓嚴格的解析模式,來避免一些意外建立的全局變量。

2. 及時解除引用

若是必需要一個全局變量來存儲大量數據,那麼請確保在用完以後將其賦值爲 null。

delete 操做符用於刪對象的某個屬性;若是沒有指向這個屬性的引用,那它最終會釋放。

但注意的一點是,儘可能不要在須要密集運算的函數中去使用 delete,這極可能會引起瀏覽器在不恰當的時候的 GC,和其餘語言同樣,JavaScript 的 GC 策略沒法避免 GC 時中止響應其餘操做,而 JavaScript 的 GC 在 50ms 甚至以上,對普通應用還好,若是是對於操做頻繁的 Web 應用或者遊戲來講,就比價煩惱了。

const Room = {
        desks: 10,
        chairs: 22
};
 
console.log(Room.desks); // 10;
 
delete Row.desks;
 
console.log(Room.desks); // undefined
複製代碼

有時候咱們雖然用 removeChild 移除了 button,可是還在 node 對象裏保存着 #button 的引用,DOM 元素還在內存裏面,須要及時解除引用。

var node = {
        button: document.getElementById('button');
};
 
document.body.removeChild(document.getElementById('button'));
複製代碼

3. 減小對象的建立
垃圾回收週期性運行,若是分配的內存很是多,或者新建很不少實例的話,那麼回收工做也會很辛苦。

儘可能避免在常常調用的方法中循環使用 new 對象,並且還要花時間對這些對象進行垃圾回收和處理。

設計模式中的享元模式就是爲了減小對象的屢次建立而來的。在咱們能夠控制的範圍內,最大限度的重用對象。

4. 內存不是緩存
緩存在需求開發中舉足輕重,可是不少時候咱們會把許多大數據緩存在內存中,致使咱們的內存佔用始終處於高位,內存對任何程序開發都是寸土寸金 的,若果不是很重要的資源,請不要直接放在內存中,或者制定過時機制,自動銷燬過時緩存。

5. 避免複雜的遞歸調用;
一般狀況下,簡單的遞歸調用還不至於致使堆棧溢出,但遇到複雜且每次調用須要 在棧裏存儲大量信息的時候,成千上萬個此類空間累積起來,很容易就超過了棧空間。

6. 合理使用的 IndexedDB
其實這個是和 JS 關係不是很大,可是對於 Web 應用的影響卻十分重要,曾經我遇到過一個用戶案例,因爲長時間的本地數據寫入,和一些上報日誌沒有被及時清除,致使用戶的瀏覽器中對應域名下的 IndexedDB 存儲高達 12GB,瀏覽器在訪問對應域名的時候,也能夠初始化 IndexedDB 和讀取本地存儲的數據,而面對如此龐大的數據,瀏覽器內存暴漲,最後崩潰,避免過分依賴 IndexedDB,無腦寫入數據而不作按期清理。

總結

這篇分享主要總結了咱們在 Web 應用,可能會遇到的一些狀況和注意的事情。

不少時候只要咱們在編碼的時候多加註意,能夠避免不少問題。

轉載自AlloyTeam: www.alloyteam.com/2019/07/138…
相關文章
相關標籤/搜索