2010-07-02 114 views
15

我們在嵌入式環境中開發應用程序。它是一個高級計算環境,在busybox Linux系統的頂部有一個完整的webbrowser。唯一的例外是系統具有有限的系統內存。當需要移除模塊以節省內存時,是否可以使用requirejs

我們的應用程序使用JavaScript構建,並在基於Webkit的瀏覽器中運行,並且包含大量按順序加載的JavaScript模塊(這不是非常高效)。

某些模塊提供了幾個模塊使用的常用功能。我們正在將我們當前的JavaScript加載程序與requirejs進行轉換,但有一個具體需求需要我們首先解決。

使用requirejs加載模塊時可以卸載它嗎?假設我們動態加載使用一個模塊:

require(["somemodule.js"], function(m) { m.run(); }); 

,對於加載和運行「somemodule」,同時也解決了「somemodule」所有的依賴和requirejs框架行之有效會參考存儲爲將來的請求「somemodule」 。

如果我們在某個時候需要回收內存,例如能夠加載和運行無限數量的模塊,我們必須在一段時間後開始刪除其中的一些模塊。 requirejs可以在不改變內部實現的情況下實現嗎?

有沒有人處理過這類問題?大多數單頁JS應用程序在桌面PC上的web瀏覽器中運行,其中內存使用通常不是主要關心的問題。

回答

17

RequireJS沒有內置的卸載功能,但可以添加它作爲您可以構建到其中的附加部件。如果您想擁有該功能,請隨時在the mailing listGitHub issue中提出。

如果你想嘗試,看它是否有助於你的情況,你需要做的是以下幾點:

1)從RequireJS模塊緩存中刪除定義的模塊。如果您沒有使用多版本支持,你可以這樣做:

var context = require.s.contexts['_']; 
delete context.defined[moduleName]; 
delete context.specified[moduleName]; 
delete context.loaded[moduleName]; 

2)然後,你可以嘗試刪除腳本標籤,看看是否有幫助:

var scripts = document.getElementsByTagName('script'); 
for (var i = scripts.length - 1; i >= 0; i--) { 
    var script = scripts[i]; 
    if (script.getAttribute('data-requiremodule') === moduleName) { 
     script.parentNode.removeChild(script); 
     break; 
    } 
} 

注意,模塊可如果另一個模塊通過定義該其他模塊的閉包函數(){}持有它,則不會被垃圾收集。那個其他模塊也需要被刪除。

您可以嘗試通過不傳入模塊作爲函數參數來限制這種影響,但只要在函數定義內部使用require(「somemodule」),只要您想獲得一系列依賴模塊並且不保留這要求返回值太長。

而且,在你上面的例子,對於使用require.def來定義自己的模塊,它應該像這樣(沒有後綴名爲.js):

require(["somemodule"], function(m) { m.run(); }); 
+0

謝謝,當我測試更多時我會回來。我們仍然使用我們自己的腳本加載器,但會轉換爲requirejs,因爲應用程序當前使用全局名稱空間,所以還有一些重構。 我在requirejs的源代碼中注意到onScriptLoad不會刪除scriptTag,但是您建議在上面的答案中這樣做。 是否出於性能原因scriptTag保存在requirejs中的DOM樹中?例如,因爲刪除腳本會在加載器中增加一些額外的處理。 我們的預加載器總是刪除onload回調中的scriptTag以保留內存。 – Ernelli 2010-07-04 14:01:06

+0

我不刪除腳本標記以使調試變得更容易(我的腳本真的加載了嗎?從哪裏來?)並且還試圖減小加載器代碼的大小。我覺得不會有太多的節省,特別是在HTML中內嵌腳本標籤的頁面上。不過,我會記錄下來測試它是否有所作爲,並且可以跨瀏覽器使用。您指出它確實有所作爲,也許我應該提供一個選項來做到這一點。有關如何驗證內存節省的任何信息,我都讚賞。 – jrburke 2010-07-05 04:35:32

+2

我們在嵌入式系統中使用的瀏覽器(IPTV機頂盒)基於Webkit。即使從文檔中刪除腳本標籤,異常的來源等也被正確標記。 我不得不做一些更多的測試,看看有多少scriptTag去除會影響內存使用情況。即使當scriptTags被移除時,JS引擎也能夠重新創建給定函數的源代碼(儘管沒有註釋)。 我們根據監控系統中可用內存的數量來完成我們所有的內存分析。 – Ernelli 2010-07-05 08:06:37

2

試試這個:require.undef(moduleName)

+2

from undef:「[...]但是,它不會從已經定義的其他模塊中移除該模塊,並且在執行時將該模塊的句柄當作依賴項,所以它只對在沒有其他模塊獲得模塊值的句柄時在錯誤情況下使用「 – Steen 2013-06-27 20:36:46

相關問題