Best practices for reducing Garbage Collector activity in Javascript
原則 盡量減少創(chuàng)建(creating)與銷毀(destroying)的過程
常見的創(chuàng)建過程
- 使用
new或者[],{} - 連接字符時
str.concat() - 進入一個有函數(shù)定義的作用域
- 進入錯誤
catch階段 - 使用一個匿名函數(shù)時
(function(){...}) - 轉(zhuǎn)換對象時
Object(number),Number.prototype.toString.call(42) - 調(diào)用內(nèi)置對象
prototype方法時Array.prototype.slice - 使用
arguments來獲取函數(shù)參數(shù)時 - 使用正則表達式來匹配或替換字符串時
優(yōu)化建議
使用對象池或者重用組件
- 將子作用域的函數(shù)提到更高級的作用域,匿名函數(shù)也可以算作這一類。在
closure compiler會自動創(chuàng)建inline函數(shù)
function loopfunc()
{
//do something
}
while(true)
{
$.each(listofthings, loopfunc);
options.ChangingVariable = newvalue;
someOtherFunction(options);
}
將快于
while(true)
{
$.each(listofthings, function(){
//do something on the list
});
someOtherFunction({
var1: value1,
var2: value2,
ChangingVariable: newvalue
});
}
- 盡量不要使用字符串于
key和dynamic addr
lookupTable[foo+x]和document.getElementById('foo-' + x)兩者都包含了字符串的創(chuàng)建.在很多情況下,你都可以將keys綁定到生命周期長的引用上,而非每次使用時,都重新創(chuàng)建它。根據(jù)瀏覽器,你可以考慮使用Map類
避免頻繁的
split調(diào)用和正則匹配將
exception catch替換為if-else
try { op(x) } catch (e) { ... }
轉(zhuǎn)換為
if (!opCouldFailOn(x)) { op(x); } else { ... }
如果你不能避免創(chuàng)建字符串, 比如向服務(wù)器發(fā)送消息時,那么你可以使用內(nèi)置的
JSON.stringify。JSON.stringify使用內(nèi)置的buffer來收集內(nèi)容,而非為它們分配內(nèi)存盡量不要頻繁地調(diào)用匿名函數(shù),這通常指某些高頻率調(diào)用的回調(diào)函數(shù)。對于這種情況,盡可能的在外部作用域聲明回調(diào)函數(shù),而不是使用匿名函數(shù)形式
避免使用
arguments,因為每次使用arguments,都要創(chuàng)建一個類似于Array的對象