一直在迷惑一个问题,那就是HTML(XHTML)他即是一个文本字符串,又是一个DOM对象,以前做东西的时候由于我对html比较熟悉,很多地方就直接使用写好的HTML字符串进行插入,例如插入一个含有内容的DIV,就直接拼接好字符串之后再将整个字符串赋给对应的DIV的innerHTML,而是不使用Javscript的DOM操作来createElement,再appendChild。
一直以来也就这么习惯了,而且这样做可以减少代码的行数,javascript要好几行代码才可以完成的事情我只需要两行就可以完成,但是随着对代码效率的重视越来越高,不得不静下心来考虑下两者之间的差异了,自己感觉自己一直以来的做法最好的地方就是减少了javascript的DOM操作,用DOM来创建一个DIV,要定义好半天,个人认为是在javascript中把浏览器解析html的工作的做了,然后把现成的DIV扔给浏览器,这样做无疑是加重了JS的负担,而直接拼接字符串的话JS就只需要负责一些逻辑,把要插入的DIV直接用字符串给浏览器,让浏览器自己去解析HTML,虽然拼接字符串很消耗效率,但是只要将+号减少,或使用数组进行字符串拼接,也会降低这一消耗。但这些毕竟只是我自己的推测,具体会怎么样,还真心里没底。
今天刚好忙完了手上的工作,看了一些书,就做些DEMO测试测试吧。
测试一:插入单个元素效率比较。
测试代码:
1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2

3
<html xmlns="http://www.w3.org/1999/xhtml">4
<head runat="server">5
<title>JS DOM操作和字符串操作效率比较</title> 6
<script type="text/javascript">7
//DOM插入单个DIV8
var domTest = function(){ 9
var div = document.createElement("div");10
div.innerHTML = "test";11
document.getElementById("test").appendChild(div);12
document.getElementById("test").removeChild(div); 13
}14
//字符串插入单个DIV 15
var strTest = function(){ 16
var div = "<div'>test</div>";17
document.getElementById("test").innerHTML += div;18
document.getElementById("test").innerHTML = "";19
}20
//测试方法21
function test(fun){22
var start = new Date(); 23
for(i=0;i<5000;i++){ 24
fun();25
}26
var end = new Date(); 27
var idstr;28
if(fun == domTest){29
idstr = "domTest";30
}else{31
idstr = "strTest";32
}33
document.getElementById(idstr).innerHTML += (end.getTime() - start.getTime()) + " , ";34
} 35
</script>36
</head>37
<body>38
<form id="form1" runat="server">39
<div id="test"></div>40
DOM: <span id="domTest"></span><br />41
STR: <span id="strTest"></span>42
</form> 43
<input type="button" onclick="test(domTest);" value="Dom测试" /> 44
<input type="button" onclick="test(strTest);" value="Str测试" />45
</body>46
</html>5000次运行5次的结果分别为:(单位:毫秒)
(可能你会说我机子怎么这么慢,没办法,公司的电脑。。。)
从上面的数据可以看出,不管何种方式,火狐都要比IE强,在IE下用直接插入html的方式要快于DOM插入,而火狐正好相反,我想这可能与IE的javascript引擎的效率有关吧。
测试二:插入多个元素效率比较。
测试代码:
1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2

3
<html xmlns="http://www.w3.org/1999/xhtml">4
<head runat="server">5
<title>JS DOM操作和字符串操作效率比较</title> 6
<script type="text/javascript">7
//DOM插入单个DIV8
var domTest = function(){ 9
var div = document.createElement("div");10
div.innerHTML = "test";11
document.getElementById("test").appendChild(div);12
}13
//字符串插入单个DIV 14
var strTest = function(){ 15
var div = "<div>test</div>";16
document.getElementById("test").innerHTML += div;17
}18
//测试方法19
function test(fun){20
var start = new Date(); 21
for(i=0;i<200;i++){ 22
fun();23
}24
var end = new Date(); 25
var idstr;26
if(fun == domTest){27
idstr = "domTest";28
}else{29
idstr = "strTest";30
}31
document.getElementById(idstr).innerHTML += (end.getTime() - start.getTime()) + " , ";32
} 33
</script>34
</head>35
<body>36
<form id="form1" runat="server">37
DOM: <span id="domTest"></span><br />38
STR: <span id="strTest"></span>39
</form> 40
<input type="button" onclick="test(domTest);" value="Dom测试" /> 41
<input type="button" onclick="test(strTest);" value="Str测试" />42
<div id="test"></div>43
</body>44
</html>45

每次插入200个,连续插入5次结果:
这次可以看出DOM操作明显要优于字符串了,因为这次添加了多少个DIV,字符串就要进行多少次+=,当然会消耗大量的效率,同时也可以看出火狐在字符串拼接上处理的非常吃力。
测试三:一次插入多个元素效率并优化字符串拼接比较。
测试代码:
1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2

3
<html xmlns="http://www.w3.org/1999/xhtml">4
<head runat="server">5
<title>JS DOM操作和字符串操作效率比较</title> 6
<script type="text/javascript">7
//DOM插入单个DIV8
var domTest = function(){9
var div = document.createElement("div");10
for(i=0;i<1000;i++){11
var div_in = document.createElement("div");12
div_in.innerHTML = "test";13
div.appendChild(div_in); 14
}15
document.getElementById("test").appendChild(div);16
}17
//字符串插入单个DIV 18
var strTest = function(){19
var div_in = new Array();20
div_in.join("");21
for(i=0;i<1000;i++){22
div_in.push("<div>test</div>");23
}24
var div = "<div>" + div_in.join("") + "</div>";25
document.getElementById("test").innerHTML += div;26
}27
//测试方法28
function test(fun){29
var start = new Date();30
fun();31
var end = new Date(); 32
var idstr;33
if(fun == domTest){34
idstr = "domTest";35
}else{36
idstr = "strTest";37
}38
document.getElementById(idstr).innerHTML += (end.getTime() - start.getTime()) + " , ";39
} 40
</script>41
</head>42
<body>43
<form id="form1" runat="server">44
DOM: <span id="domTest"></span><br />45
STR: <span id="strTest"></span>46
</form> 47
<input type="button" onclick="test(domTest);" value="Dom测试" /> 48
<input type="button" onclick="test(strTest);" value="Str测试" />49
<div id="test"></div>50
</body>51
</html>52

构造1000个DIV,然后一次性插入:
结果出来了,HTML字符串获胜!
不过从结果中也可以看出,直接插入html字符串随着插入次数的增多,效率也会慢下来,这就需要在字符串处理上格外的小心了。
看来我的观点还是有一定道理的,把该浏览器解析的东西就交给浏览器吧,让javascript有更多的精力去处理逻辑上的事情。毕竟目前javascript只有一条进程啊。
从上面的几个试验综合起来我们还能看到,很多情况下其实采用什么方法并不重要,重要的是我们要根据自己的需求,能够想到会遇到什么样的瓶颈,然后去避开他,或寻求最佳折中的方案。
多的也不会说了 ,大道理不太会讲,就暂且到此吧。