最近遇到js的效率问题,是关于在页面中新增元素的问题;
假设:我们有页面如下
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><HTML>
<HEAD>
</HEAD>
<BODY>
<divid="div1"></div>
</BODY>
<script>
//脚本位置
</script>
</HTML>
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><HTML>
<HEAD>
</HEAD>
<BODY>
<divid="div1"></div>
</BODY>
<script>
//脚本位置
</script>
</HTML>
现在,我们要往div1中添加对象,大家都知道在为web页面增加一个元素时可以使用如下代码:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
// 方法1
div1.innerHTML='<ahref="">测试</a>';
或者:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
div1.appendChild(a);
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
// 方法2
vara=document.createElement('a');
a.innertText='测试';
div1.appendChild(a);
在网上搜索到一个探讨js效率问题的文章,其大概意思是说方法2的效率高,其对比代码如下
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->//方法1
functioninit(){
varstaDate=newDate();
vardoc=window.document;
for(vari=0;i<100;i++){
varstr="<divid='div_'"+i+"'style='width:100px;height:20px;background-color:#eee'>test</div>";
container.innerHTML+=str;
}
alert(newDate-staDate);
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->//方法1
functioninit(){
varstaDate=newDate();
vardoc=window.document;
for(vari=0;i<100;i++){
varstr="<divid='div_'"+i+"'style='width:100px;height:20px;background-color:#eee'>test</div>";
container.innerHTML+=str;
}
alert(newDate-staDate);
}
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->//方法2
functioninit(){
varstaDate=newDate();
vardoc=window.document;
for(vari=0;i<100;i++){
varoDiv=doc.createElement("div");
varoText=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(newDate-staDate);
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->//方法2
functioninit(){
varstaDate=newDate();
vardoc=window.document;
for(vari=0;i<100;i++){
varoDiv=doc.createElement("div");
varoText=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(newDate-staDate);
}
其页面中有:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><divid="container"></div>
<inputtype="button"value="start"onclick="init();"/>
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><divid="container"></div>
<inputtype="button"value="start"onclick="init();"/>
从执行效果来看方案2要比方案1快10倍左右,到底这是不是真的呢?其实上面的测试代码是有待商榷的,且看其方法1中的循环代码:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->for(vari=0;i<100;i++){
varstr="<divid='div_'"+i+"'style='width:100px;height:20px;background-color:#eee'>test</div>";
container.innerHTML+=str;
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->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的性能,于是写了下面的测试代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><HTML>
<HEAD>
</HEAD>
<BODY>
<inputtype="button"value="测试1"onclick="test1()"/><inputtype=textreadonlyid=t1>
<inputtype="button"value="测试2"onclick="test2()"/><inputtype=textreadonlyid=t2>
<inputtype="button"value="清空"onclick="div1.innerHTML='';div2.innerHTML='';t1.value='';t2.value='';"/>
<divid="div1"></div>
<divid="div2"></div>
</BODY>
<script>
functiontest1()
{
vard=newDate();
varbuf=newArray();
for(varn=0;n<1000;n++)
{
buf.push('<ahref="">测试');
buf.push(n);
buf.push('</a>');
}
div1.innerHTML=buf.join('');
t1.value='耗时:'+(newDate()-d);
}
functiontest2()
{
vard=newDate();
for(varn=0;n<1000;n++)
{
vare=document.createElement('a');
e.href='';
e.innerText='测试'+n;
div2.appendChild(e);
}
t2.value='耗时:'+(newDate()-d);
}
</script>
</HTML>
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><HTML>
<HEAD>
</HEAD>
<BODY>
<inputtype="button"value="测试1"onclick="test1()"/><inputtype=textreadonlyid=t1>
<inputtype="button"value="测试2"onclick="test2()"/><inputtype=textreadonlyid=t2>
<inputtype="button"value="清空"onclick="div1.innerHTML='';div2.innerHTML='';t1.value='';t2.value='';"/>
<divid="div1"></div>
<divid="div2"></div>
</BODY>
<script>
functiontest1()
{
vard=newDate();
varbuf=newArray();
for(varn=0;n<1000;n++)
{
buf.push('<ahref="">测试');
buf.push(n);
buf.push('</a>');
}
div1.innerHTML=buf.join('');
t1.value='耗时:'+(newDate()-d);
}
functiontest2()
{
vard=newDate();
for(varn=0;n<1000;n++)
{
vare=document.createElement('a');
e.href='';
e.innerText='测试'+n;
div2.appendChild(e);
}
t2.value='耗时:'+(newDate()-d);
}
</script>
</HTML>
经测试发现:
在创建的对象较少(0-大约10左右)时,innerHTML和createElement效率差不多,测试值悠忽不定 在创建对象多于20时,innerHTML要比createElement效率高很多,平均测试差不多createElement耗时是innerHTML的两倍。总结:其实效率也在于编写的代码,在知道可用的API的效率后,怎么编写代码也是非常重要的,否则应由的执行效率不能体现出来,就如上面从网上搜到的那些代码,得出一个与事实相悖的结论。