Javascript DOM操作与html字符串操作效率比较

本文通过三个实验对比了HTML字符串插入与DOM操作在不同浏览器中的效率,揭示了字符串拼接优化的重要性。

一直在迷惑一个问题,那就是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测试测试吧。


测试一:插入单个元素效率比较。

 

简述我们来分别用DOM和字符串的方式来插入一个简单的DIV对象,分别用IE6和火狐2来比较下效率(IE7+和火狐3就先不弄了,最近机子卡,不想开虚机跑了。)

 

测试代码:

ContractedBlock.gifExpandedBlockStart.gifCode:插入单个元素效率比较
 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>    
 6ExpandedBlockStart.gifContractedBlock.gif    <script type="text/javascript">
 7    //DOM插入单个DIV
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    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   
15ExpandedSubBlockStart.gifContractedSubBlock.gif    var strTest = function(){    
16        var div = "<div'>test</div>";
17        document.getElementById("test").innerHTML += div;
18        document.getElementById("test").innerHTML = "";
19    }

20    //测试方法
21ExpandedSubBlockStart.gifContractedSubBlock.gif    function test(fun){
22        var start = new Date();        
23ExpandedSubBlockStart.gifContractedSubBlock.gif        for(i=0;i<5000;i++){        
24            fun();
25        }

26        var end = new Date();        
27        var idstr;
28ExpandedSubBlockStart.gifContractedSubBlock.gif        if(fun == domTest){
29            idstr = "domTest";
30ExpandedSubBlockStart.gifContractedSubBlock.gif        }
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次的结果分别为:(单位:毫秒)

 

测试结果

IE6:

DOM: 2093 , 2094 , 2078 , 2047 , 2063    平均:2075

STR: 1782 , 1766 , 1750 , 1766 , 1765     平均:1766

 FF2:

DOM:  937 ,   938 ,   938 ,  937 ,   953     平均:941

STR: 1313 , 1312 , 1328 , 1312 , 1328     平均:1319

 (可能你会说我机子怎么这么慢,没办法,公司的电脑。。。)

从上面的数据可以看出,不管何种方式,火狐都要比IE强,在IE下用直接插入html的方式要快于DOM插入,而火狐正好相反,我想这可能与IE的javascript引擎的效率有关吧。

 

测试二:插入多个元素效率比较。

简述上个测试只是比较插入一个DIV的效率,这次对代码稍作修改,插入完成之后不再清除,也就是连着插入多个,然后比较下效率。

测试代码:

ContractedBlock.gifExpandedBlockStart.gifCode:插入多个元素效率比较
 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>    
 6ExpandedBlockStart.gifContractedBlock.gif    <script type="text/javascript">
 7    //DOM插入单个DIV
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    var domTest = function(){    
 9        var div = document.createElement("div");
10        div.innerHTML = "test";
11        document.getElementById("test").appendChild(div);
12    }

13    //字符串插入单个DIV   
14ExpandedSubBlockStart.gifContractedSubBlock.gif    var strTest = function(){    
15        var div = "<div>test</div>";
16        document.getElementById("test").innerHTML += div;
17    }

18    //测试方法
19ExpandedSubBlockStart.gifContractedSubBlock.gif    function test(fun){
20        var start = new Date();        
21ExpandedSubBlockStart.gifContractedSubBlock.gif        for(i=0;i<200;i++){        
22            fun();
23        }

24        var end = new Date();        
25        var idstr;
26ExpandedSubBlockStart.gifContractedSubBlock.gif        if(fun == domTest){
27            idstr = "domTest";
28ExpandedSubBlockStart.gifContractedSubBlock.gif        }
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次结果:

 

测试结果

IE6:

DOM: 63 , 79 , 78 , 78 , 94 

点5次DOM之后刷新页面再测html字符串的:

 

STR: 375 , 1015 , 1656 , 2312 , 3000 

FF2:

DOM: 32 , 31 , 31 , 32 , 31 

同样点5次DOM之后刷新页面再测html字符串的:

STR: 13781 , 56984 , 。。。后面不敢点了。 

这次可以看出DOM操作明显要优于字符串了,因为这次添加了多少个DIV,字符串就要进行多少次+=,当然会消耗大量的效率,同时也可以看出火狐在字符串拼接上处理的非常吃力。

 

测试三:一次插入多个元素效率并优化字符串拼接比较。

简述上次测试是反复多次插入多个元素,这次测试我们先构造好多个元素,然后一次性插入,比较效率,同时吸取上次字符串拼接的教训,这次用数组来对字符串拼接进行优化。

测试代码:

ContractedBlock.gifExpandedBlockStart.gifCode:一次插入多个元素效率并优化字符串拼接比较
 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>    
 6ExpandedBlockStart.gifContractedBlock.gif    <script type="text/javascript">
 7    //DOM插入单个DIV
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    var domTest = function(){
 9        var div = document.createElement("div");
10ExpandedSubBlockStart.gifContractedSubBlock.gif        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   
18ExpandedSubBlockStart.gifContractedSubBlock.gif    var strTest = function(){
19        var div_in = new Array();
20        div_in.join("");
21ExpandedSubBlockStart.gifContractedSubBlock.gif        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    //测试方法
28ExpandedSubBlockStart.gifContractedSubBlock.gif    function test(fun){
29        var start = new Date();
30        fun();
31        var end = new Date();        
32        var idstr;
33ExpandedSubBlockStart.gifContractedSubBlock.gif        if(fun == domTest){
34            idstr = "domTest";
35ExpandedSubBlockStart.gifContractedSubBlock.gif        }
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,然后一次性插入:

 

测试结果

IE6:

DOM: 297 , 313 , 312 , 313 , 313 

刷新之后:

STR: 31 , 32 , 31 , 63 , 79 

FF2:

DOM: 109 , 109 , 110 , 109 , 110

 

刷新之后:

STR: 15 , 31 , 62 , 78 , 94 

结果出来了,HTML字符串获胜!

不过从结果中也可以看出,直接插入html字符串随着插入次数的增多,效率也会慢下来,这就需要在字符串处理上格外的小心了。

看来我的观点还是有一定道理的,把该浏览器解析的东西就交给浏览器吧,让javascript有更多的精力去处理逻辑上的事情。毕竟目前javascript只有一条进程啊。

 从上面的几个试验综合起来我们还能看到,很多情况下其实采用什么方法并不重要,重要的是我们要根据自己的需求,能够想到会遇到什么样的瓶颈,然后去避开他,或寻求最佳折中的方案。

多的也不会说了 ,大道理不太会讲,就暂且到此吧。

转载于:https://www.cnblogs.com/aaa/articles/1358161.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值