对《30个提高Web程序执行效率的好经验》的理解

阅读了博客园发布的IT文章《30个提高Web程序执行效率的好经验》,这30条准则对我们web开发是非常有用的,不过大家可能对其中的一些准则是知其然而不知其所以然。

下面是我对这些准则的理解和分析,有些有关JS性能的准则,我也测试了它们的差异,大家可以下载DEMO页面,如有理解不正确的地方,请大家指正。也非常欢迎大家补充。

测试环境:

OS:Vista;

Processor:3.40GHz;

Memory: 2.00GB;

System type: 32-bit Operating System;

Browser: IE8, Forefox 3.5.7, Chrome4.0.249

   1. 尽量避免使用DOM。当需要反复使用DOM时,先把对DOM的引用存到JavaScript本地变量里再使用。使用设置innerHTML的方法来替换document.createElement/appendChild() 法。

我们可以用如下的代码进行测试:

function testInnerHTML(){

var div1 = document.getElementById("testDiv");

var startTime = new Date();

var buf = new Array();

for (var n = 0; n < 5000; n ++){

buf.push('<a href="">test');

buf.push(n);

buf.push('</a>');

}

div1.innerHTML = buf.join('');

document.getElementById('divShowTime1').innerHTML = '耗时1' +  (new Date() - startTime) + 'ms';

div1.innerHTML = "";

}

function testCreateElement(){

var div1 = document.getElementById("testDiv");

var startTime = new Date();

for (var n = 0; n < 5000; n ++){

var e = document.createElement('a');

e.href = '';

e.innerText = 'test' + n;

div1.appendChild(e);

}

document.getElementById('divShowTime2').innerHTML = '耗时2' +  (new Date() - startTime) + 'ms';

div1.innerHTML = "";

}

 

测试结果:

 

 

IE8

Firefox

Chrome

1

耗时1134ms
耗时2857ms

耗时1570ms
耗时2658ms

耗时161ms
耗时247ms

2

耗时1131ms
耗时2846ms

耗时1474ms
耗时2610ms

耗时158ms
耗时248ms

3

耗时1131ms
耗时2927ms

耗时1673ms
耗时2674ms

耗时157ms
耗时249ms

4

耗时1132ms
耗时2846ms

耗时1540ms
耗时2686ms

耗时155ms
耗时246ms

测试结果显示使用innerHTML对比document.createElement/appendChild()方法,在IE8中,效率的提高是非常明显的,但是在FirefoxChrome中,差别不大。

2. eval()有问题,new Fuction()构造函数也是,尽量避免使用它们。

eval方式比直接调用方式多了一步解析的过程,所以尽量避免使用它,如果必须用它,则最好是把调用的代码包装到函数中,然后eval这个函数,这样减少了解析的时间。eval函数的效率,我们可以用如下的代码测试:

 

function testNoEval() {

var startTime = new Date();

for(var i=0; i<500000; i++) {

var str = 'test';

}

var endTime = new Date();

document.getElementById('divShowTime1').innerHTML = '耗时1' +  (endTime - startTime) + 'ms';

}

function testEval() {

var startTime = new Date();

eval("for(var i=0; i<500000; i++) { var str = 'test'; }");

var endTime = new Date();

document.getElementById('divShowTime2').innerHTML = '耗时2' +  (endTime - startTime) + 'ms';

}

 

测试结果:

 

 

IE8

Firefox

Chrome

1

耗时185ms
耗时2251ms

耗时12ms
耗时2203ms

耗时11ms
耗时2340ms

2

耗时182ms
耗时2251ms

耗时12ms
耗时2204ms

耗时12ms
耗时2344ms

3

耗时181ms
耗时2250ms

耗时12ms
耗时2205ms

耗时11ms
耗时2338ms

4

耗时182ms
耗时2251ms

耗时12ms
耗时2213ms

耗时12ms
耗时2344ms

 

测试发现,eval的效率明显慢很多,尤其在Firefoxchrome中。 new Fuction的执行原理和eval类似,所以效率也是不高。

3. 拒绝使用with语句。 它会导致当你引用这个变量时去额外的搜索这样的一个命名空间,with里的代码在编译时期是完全未知的。

原因明确,不过使用with语句,代码会非常简洁,我个人还是经常使用这个语句的。

4. 使用for()循环替代for…in 环。因为for…in循环在开始循环之前需要Script引擎创建一个含有所有可循环属性的 List,需要多检查一次。

原因明确,没有补充。

5. try-catch语句放在循环外面,不要放在循环里面,因为异常是很少发生的,放在外面避免每次都要执行 它们。

原因明确,这是我认为使用任何语言都有必要遵守的准则。

6. 甚至圣经里都提到过这个不要全局的。全局变量的生命周期贯穿整个脚本的生命周期,而本地变量的存在范围随着本地命名空间的销毁而消失。当在函数或其它地方引用一个全局变量时,脚 本引擎需要搜索整个全局命名空间。

防止内存泄漏和提高查找解析速度,另外,变量定义在最小使用范围内,代码的可读性好。

7. fullName += 'John'; fullName += 'Holdings';执行速度快于fullName += 'John' + 'Holdings';

还是采用测试代码:

 

function testString1() {

var startTime = new Date();

for(var i=0; i<500000; i++) {

var fullName = "";

fullName += 'John';

fullName += 'Holdings';

}

var endTime = new Date();

document.getElementById('divShowTime1').innerHTML = '耗时1' +  (endTime - startTime) + 'ms';

}

function testString2() {

var startTime = new Date();

for(var i=0; i<500000; i++) {

var fullName = "";

fullName += 'John' + 'Holdings';

}

var endTime = new Date();

document.getElementById('divShowTime2').innerHTML = '耗时2' +  (endTime - startTime) + 'ms';

}

 

测试结果:

 

IE8

Firefox

Chrome

1

耗时1492ms
耗时2477ms

耗时1151ms
耗时27ms

耗时152ms
耗时251ms

2

耗时1532ms
耗时2456ms

耗时1150ms
耗时27ms

耗时150ms
耗时251ms

3

耗时1493ms
耗时2454ms

耗时1148ms
耗时27ms

耗时153ms
耗时250ms

4

耗时1491ms
耗时2466ms

耗时1204ms
耗时28ms

耗时151ms
耗时250ms

 

测试结果出乎意料,在IE8chrome中,两者的效率差不多,但是在Firefox中,第一种写法反而比第二种慢很多。IE6下测试也是如此,看来这条规则还有待进一步研究。

8. 如果你需要把多个字符串连接起来,最好是把他们做成一个数组,然后调用join()方法实现这个操作。这种方式在生成HTML片段时尤其 有效。

验证还是用测试代码:

 

function testNoJoin(){

var startTime = new Date();

var testStr = "abcdefghqwertyuiolkjmzxv";

var result = "";

for(var i=0; i<50000; i++) result += testStr;

document.getElementById('divShowTime1').innerHTML = '耗时1' +  (new Date() - startTime) + 'ms';

}

function testJoin(){

var startTime = new Date();

var testStr = "abcdefghqwertyuiolkjmzxv";

var result = "";

var strs = new Array();

for(var i=0; i<50000; i++) strs[i] = testStr;

result = strs.join("");

document.getElementById('divShowTime2').innerHTML = '耗时2' +  (new Date() - startTime) + 'ms';

strs = null;

}

 

测试结果:

 

IE8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值