也谈Javascript的效率,createElement和innerHTML,为innerHTML平反

最近遇到js的效率问题,是关于在页面中新增元素的问题;

假设:我们有页面如下

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < HTML >
< HEAD >
</ HEAD >
< BODY >
< div id ="div1" ></ div >
</ BODY >
< script >
// 脚本位置
</ script >
</ HTML >

现在,我们要往div1中添加对象,大家都知道在为web页面增加一个元素时可以使用如下代码:


<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->

// 方法1

div1.innerHTML='<ahref="">测试</a>';

或者:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->

// 方法2

vara=document.createElement('a');

a.innertText = ' 测试 ' ;
div1.appendChild(a);

在网上搜索到一个探讨js效率问题的文章,其大概意思是说方法2的效率高,其对比代码如下

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> // 方法1
function init(){
var staDate = new Date();
var doc = window.document;
for ( var i = 0 ;i < 100 ;i ++ ){
var str = " <divid='div_' " + i + " 'style='width:100px;height:20px;background-color:#eee'>test</div> " ;
container.innerHTML
+= str;
}
alert(
new Date - staDate);
}
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> // 方法2
function init(){
var staDate = new Date();
var doc = window.document;
for ( var i = 0 ;i < 100 ;i ++ ){
var oDiv = doc.createElement( " div " );
var oText = doc.createTextNode( " text " );
oDiv.appendChild(oText);
container.appendChild(oDiv);
oDiv.style.id
= " div_ " + i;
oDiv.style.width
= " 100px " ;
oDiv.style.height
= " 20px " ;
oDiv.style.backgroundColor
= " #eee " ;
}
alert(
new Date - staDate);
}

其页面中有:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < div id ="container" ></ div >
< input type ="button" value ="start" onclick ="init();" />

从执行效果来看方案2要比方案1快10倍左右,到底这是不是真的呢?其实上面的测试代码是有待商榷的,且看其方法1中的循环代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> for(vari=0;i < 100 ;i++){
varstr
="<divid='div_'" +i+"'style ='width:100px; height:20px;background-color:#eee' > test </ div > ";
container.innerHTML+=str;
}

其中有很多字符串操作,而且除了使用+号来连接字符串外,还使用了+=操作符,这就是问题的所在了,在javascript中这种操作字符串的做法是严重影响效率的,所以使用上面的方法来测试createEmenent和innerHTML的效率对innerHTML是不公平的, 据此看来很可能是字符串操作吃掉了innerHTML的性能,于是写了下面的测试代码

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < HTML >
< HEAD >
</ HEAD >
< BODY >
< input type ="button" value ="测试1" onclick ="test1()" />< input type =text readonlyid =t1 >
< input type ="button" value ="测试2" onclick ="test2()" />< input type =text readonlyid =t2 >
< input type ="button" value ="清空" onclick ="div1.innerHTML='';div2.innerHTML='';t1.value='';t2.value='';" />
< div id ="div1" ></ div >
< div id ="div2" ></ div >
</ BODY >
< script >
function test1()
{
var d = new Date();
var buf = new Array();
for ( var n = 0 ;n < 1000 ;n ++ )
{
buf.push(
' <ahref="">测试 ' );
buf.push(n);
buf.push(
' </a> ' );
}

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

t1.value
= ' 耗时: ' + ( new Date() - d);
}

function test2()
{
var d = new Date();
for ( var n = 0 ;n < 1000 ;n ++ )
{
var e = document.createElement( ' a ' );
e.href
= '' ;
e.innerText
= ' 测试 ' + n;
div2.appendChild(e);
}

t2.value
= ' 耗时: ' + ( new Date() - d);
}
</ script >
</ HTML >

经测试发现:

  1. 在创建的对象较少(0-大约10左右)时,innerHTML和createElement效率差不多,测试值悠忽不定
  2. 在创建对象多于20时,innerHTML要比createElement效率高很多,平均测试差不多createElement耗时是innerHTML的两倍。

总结:其实效率也在于编写的代码,在知道可用的API的效率后,怎么编写代码也是非常重要的,否则应由的执行效率不能体现出来,就如上面从网上搜到的那些代码,得出一个与事实相悖的结论。

你可能感兴趣的:(JavaScript,html,Web,脚本)