Best practices for reducing Garbage Collector activity in Javascript
原则 尽量减少创建(creating)与销毁(destroying)的过程
常见的创建过程
- 使用
new或者[],{} - 连接字符时
str.concat() - 进入一个有函数定义的作用域
- 进入错误
catch阶段 - 使用一个匿名函数时
(function(){...}) - 转换对象时
Object(number),Number.prototype.toString.call(42) - 调用内置对象
prototype方法时Array.prototype.slice - 使用
arguments来获取函数参数时 - 使用正则表达式来匹配或替换字符串时
优化建议
使用对象池或者重用组件
- 将子作用域的函数提到更高级的作用域,匿名函数也可以算作这一类。在
closure compiler会自动创建inline函数
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)两者都包含了字符串的创建.在很多情况下,你都可以将keys绑定到生命周期长的引用上,而非每次使用时,都重新创建它。根据浏览器,你可以考虑使用Map类
避免频繁的
split调用和正则匹配将
exception catch替换为if-else
try { op(x) } catch (e) { ... }
转换为
if (!opCouldFailOn(x)) { op(x); } else { ... }
如果你不能避免创建字符串, 比如向服务器发送消息时,那么你可以使用内置的
JSON.stringify。JSON.stringify使用内置的buffer来收集内容,而非为它们分配内存尽量不要频繁地调用匿名函数,这通常指某些高频率调用的回调函数。对于这种情况,尽可能的在外部作用域声明回调函数,而不是使用匿名函数形式
避免使用
arguments,因为每次使用arguments,都要创建一个类似于Array的对象