精华帖 (2) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-10-22
让我再次想起这个问题源于前面的一次面试,记得当时问我的一个问题是“创建节点选用哪种方式比较好”,我当时的回答是:IE下面innerHTML效率更高,而非IE浏览器下面则是createElement更好。可是,面试官觉得我的结论是不正确的,“在各种浏览器下面,innerHTML都要比createElement效率更高的”! 把回来后的一趟子事完成后,开始着手证明一下,其实,我当时回答的也不是没有“证据”,因为我在一个前端博客(DOM操作的性能优化)上面看到这样的结论:“appendChild和innerHTML的效率也是要分浏览器来考虑到,IE浏览器操作innerHTML的效率非常高,而FF和Opera会慢些,尤其是FF,当innerHTML内部元素很多的时候效率极低,毕竟innerHTML是IE首创并发扬光大的。所以可以这么讲:IE的innerHTML效率优于appendChild,而Firefox则是相反。。。”,可惜当时自己看到这样的结论却没有做测试,无demo,无真相啊! 好了,下面是我的三个测试code: <body> <div id="container"></div> <input type="button" value="start" onclick="init()" /> </body> CODE1: function init(){ var staDate = new Date(); var container = document.getElementById("container"); for(var i=0;i<500;i++){ var str="<div>test</div>"; container.innerHTML += str; } alert(new Date - staDate); } CODE2: function init(){ var staDate = new Date(); var container = document.getElementById("container"); for(var i=0;i<500;i++){ var odiv = document.createElement("div"); var otext = document.createTextNode("text"); odiv.appendChild(otext); container.appendChild(odiv); } alert(new Date - staDate); } CODE3: function init(){ var staDate = new Date(); var container = document.getElementById("container"); var arr = []; for(var i=0;i<500;i++){ var str="<div>test</div>"; arr.push(str); } container.innerHTML = arr.join(""); alert(new Date - staDate); } 下面是某一次测试得出的数据: IE7: 3469 109 16 FF: 6072 35 14 Chrome: 3170 3 2 可以看出,第一个程序耗时很大一部分是由于字符串的连接操作造成的,这个问题我以前探讨过:也说说JavaScript字符串连接的效率,另外,innerHTML的效率(耗时)比createElement再append要高! 更改程序,再次验证: CODE4: //在代码2的基础上增加一个数量节 function init(){ var staDate = new Date(); var container = document.getElementById("container"); for(var i=0;i<5000;i++){ var odiv = document.createElement("div"); var otext = document.createTextNode("text"); odiv.appendChild(otext); container.appendChild(odiv); } alert(new Date - staDate); } CODE5: //比代码3更严谨,只计算操作innerHTML的时间 function init(){ var container = document.getElementById("container"); var arr = []; for(var i=0;i<5000;i++){ var str="<div>test</div>"; arr.push(str); } var str = arr.join(""); var staDate = new Date(); container.innerHTML = str; alert(new Date - staDate); } IE7: 922 78 FF: 372 144 Chrome: 32 28 看来,IE浏览器操作innerHTML的效率确实非常高,当innerHTML内容很多时,IE效率比FF高,“毕竟innerHTML是IE首创并发扬光大的”,不过,innerHTML的效率显然还是比createElement和append要高! 看来,面试官的结论是正确的,在敬佩的同时对自己当时不作测试感到惋惜! 最后,感谢zhubiao大哥在百忙中抽出时间和我讨论,让我知道“innerHTML属于‘静态’的操作,消耗内存小一点。creatElement相比之下会更消耗内存…” 文章结尾,附上网上一些大牛对这个问题的探讨: PPK:Benchmark - W3C DOM vs. innerHTML Dustindiaz:innerHTML and DOM Methods 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-10-22
测试很重要,赞楼主。
另,关于字符串拼接,只有ie6和ie7下,因为内部实现的问题,导致 + 性能低下。 面向未来编程的话,还是推荐用 + 号拼接,只在真有性能问题的地方,针对ie7-用下array中转。 对于纯字符串(无变量)拼接,比如 var s = "dgdhdh" + "hdhs" + .... 用 + 号还可以让压缩优化,压缩后直接变成 s = "dshdhdjfjgfjg". 这样性能无疑是最高的。 |
|
返回顶楼 | |
发表时间:2009-10-22
最后修改:2009-10-22
lifesinger 写道
测试很重要,赞楼主。
另,关于字符串拼接,只有ie6和ie7下,因为内部实现的问题,导致 + 性能低下。 面向未来编程的话,还是推荐用 + 号拼接,只在真有性能问题的地方,针对ie7-用下array中转。 对于纯字符串(无变量)拼接,比如 var s = "dgdhdh" + "hdhs" + .... 用 + 号还可以让压缩优化,压缩后直接变成 s = "dshdhdjfjgfjg". 这样性能无疑是最高的。 谢谢射雕兄! 您说的好!对于纯字符串(无变量)拼接用 + 号在某一些情况自然更好,不过记得如果不是纯字符串拼接的时候,用 + 会出现问题:
var a = 22; var b = 33; var c = "test"; alert(a+b+c); alert(a+c+b); O(∩_∩)O~ 我在处理这样的问题时,并没有像您讲的那样非常严谨的针对特殊情况特殊处理,我直接模拟了一个StringBuffer对象, |
|
返回顶楼 | |
发表时间:2009-10-22
字符串的拼接也可以采用 ['abc', 'def'].join(''), 这样效率会比‘+’操作高不少,尤其是IE6
|
|
返回顶楼 | |
发表时间:2009-10-23
冯冀川 写道
字符串的拼接也可以采用 ['abc', 'def'].join(''), 这样效率会比‘+’操作高不少,尤其是IE6
我前面说的封装一个StringBuffer对象其实也就是这个意思:通过Array的push和join操作,具体效率的数据上的对比,可以参看我博客里面的一篇文章:也说说JavaScirpt字符串连接的效率 ,不过那篇文章里面我并没有封装StringBuffer对象
|
|
返回顶楼 | |
发表时间:2009-10-23
可以看出,第一个程序耗时很大一部分是由于字符串的连接操作造成的
var str="<div>test</div>"; container.innerHTML += str; 这不是字符串的效率,你改变了元素的innerHTML直接触发了dom渲染(瞎编的词,总之就是浏览器要对页面重新处理), 代码3只进行了一次渲染,所以要快很多 createElement感觉上就比字符串操作费资源啊 |
|
返回顶楼 | |
发表时间:2009-10-23
raiha 写道
可以看出,第一个程序耗时很大一部分是由于字符串的连接操作造成的
var str="<div>test</div>"; container.innerHTML += str; 这不是字符串的效率,你改变了元素的innerHTML直接触发了dom渲染(瞎编的词,总之就是浏览器要对页面重新处理), 代码3只进行了一次渲染,所以要快很多 createElement感觉上就比字符串操作费资源啊 页面渲染(即:reflow)肯定要消耗时间,可是字符串的拼接也是很耗时的,请楼上看看我的文章:也说说JavaScript字符串连接的效率,具体的不在此赘述。 楼上可以针对自己的观点也做做测试,这样既能得出可靠的结论,而且也是一种知识的沉淀, |
|
返回顶楼 | |
发表时间:2009-10-23
clone168 写道
raiha 写道
可以看出,第一个程序耗时很大一部分是由于字符串的连接操作造成的
var str="<div>test</div>"; container.innerHTML += str; 这不是字符串的效率,你改变了元素的innerHTML直接触发了dom渲染(瞎编的词,总之就是浏览器要对页面重新处理), 代码3只进行了一次渲染,所以要快很多 createElement感觉上就比字符串操作费资源啊 页面渲染(即:reflow)肯定要消耗时间,可是字符串的拼接也是很耗时的,请楼上看看我的文章:也说说JavaScript字符串连接的效率,具体的不在此赘述。 楼上可以针对自己的观点也做做测试,这样既能得出可靠的结论,而且也是一种知识的沉淀,
要比字符串拼接的效率应该用这个方法跟CODE3比较;那个CODE1在循环改变innerHTML,跟字符串拼接没法比
function init(){ var staDate = new Date(); var containerStr = ""; var container = document.getElementById("container"); for(var i=0;i<5000;i++){ var str="<div>test</div>"; containerStr += str; } container.innerHTML = containerStr alert(new Date - staDate); } IE6下用数据拼串比+要快很多; ff2和chrom速度没什么差别(50000次循环); 这个结果跟你那个字符串拼接效率的文章是一致的
|
|
返回顶楼 | |
发表时间:2009-10-23
raiha 写道
clone168 写道
raiha 写道
可以看出,第一个程序耗时很大一部分是由于字符串的连接操作造成的
var str="<div>test</div>"; container.innerHTML += str; 这不是字符串的效率,你改变了元素的innerHTML直接触发了dom渲染(瞎编的词,总之就是浏览器要对页面重新处理), 代码3只进行了一次渲染,所以要快很多 createElement感觉上就比字符串操作费资源啊 页面渲染(即:reflow)肯定要消耗时间,可是字符串的拼接也是很耗时的,请楼上看看我的文章:也说说JavaScript字符串连接的效率,具体的不在此赘述。 楼上可以针对自己的观点也做做测试,这样既能得出可靠的结论,而且也是一种知识的沉淀,
要比字符串拼接的效率应该用这个方法跟CODE3比较;那个CODE1在循环改变innerHTML,跟字符串拼接没法比
function init(){ var staDate = new Date(); var containerStr = ""; var container = document.getElementById("container"); for(var i=0;i<5000;i++){ var str="<div>test</div>"; containerStr += str; } container.innerHTML = containerStr alert(new Date - staDate); } IE6下用数据拼串比+要快很多; ff2和chrom速度没什么差别(50000次循环); 这个结果跟你那个字符串拼接效率的文章是一致的
嗯,测试很重要! 不过其实我在这篇文章里面强调的不是字符串的拼接的问题,而是比较两种新建节点方式的效率,欢迎大家继续拍砖 |
|
返回顶楼 | |
发表时间:2009-10-23
最后修改:2009-10-23
lifesinger 写道 测试很重要,赞楼主。
另,关于字符串拼接,只有ie6和ie7下,因为内部实现的问题,导致 + 性能低下。 面向未来编程的话,还是推荐用 + 号拼接,只在真有性能问题的地方,针对ie7-用下array中转。 对于纯字符串(无变量)拼接,比如 var s = "dgdhdh" + "hdhs" + .... 用 + 号还可以让压缩优化,压缩后直接变成 s = "dshdhdjfjgfjg". 这样性能无疑是最高的。 面向未来编程的话,还是推荐用 + 号拼接 想知道为什么 能不能详细说说. 谢谢 |
|
返回顶楼 | |