innerHTML和W3C之DOM在脚本编程中的中庸之道

  这篇文章并非关于innerHTMLW3CDOM方法孰优孰劣的口水战。关于它们的PK在很多朋友的文章中都已经可以整理为精彩的小说,这里就不再为故事添加情节。

    本文阅网博客要给大家分享的内容是,在前端应用中若涉及大量元素elements操作,如何来更好整合使用innerHTML和DOM方法,以使页面的脚本执行效率能够潜在地提升数百倍,比单纯使用innerHTML或DOM方法在浏览器性能实践、实战PK中,在速度方面实实在在地提升到极致。

    在一些浏览器中,尤其是在常用的Firefox火狐浏览中,尽管innerHTML一般要比DOM方法执行速度要快很多,但是innerHTML在销毁已经存在的元素方面所消耗的时间确实表现不佳,innerHTML在创建元素时的速度和在销毁元素时的速度是不成比例的。搞清楚这一点以后,我们考虑可以尝试整合使用DOM方法销毁元素(通过标准DOM方法移除待销毁内容的父节点)的牛叉速度,与使用innerHTML创建新元素的牛叉速度。(这种技术在在做一个正则表达式应用的时候发现的,是性能提升的重要举措之一。)

    代码如下:

  1. function replaceHtml(el, html) {
  2.     var oldEl = typeof el === "string" ? document.getElementById(el) : el;
  3.     /*@cc_on // 单纯innerHTML在IE中会稍微更快一些
  4.         oldEl.innerHTML = html;
  5.         return oldEl;
  6.     @*/
  7.     var newEl = oldEl.cloneNode(false);
  8.     newEl.innerHTML = html;
  9.     oldEl.parentNode.replaceChild(newEl, oldEl);
  10.     /* 因为我们只是从DOM中移除旧元素,所以返回一个新元素引用用作恢复 */
  11.     return newEl;
  12. };

 
    在项目中,就可使用上面的 el = replaceHtml(el, newHtml)替代el.innerHTML = newHtml。

    我认为innerHTML已经够快了,...真的有必要这样做吗??

    这个问题依赖于您要重写多少个元素elements了。在我曾经的一个开发中,每按下一个键,甚至可能就触发了销毁并创建数以千记的元素(为了页面显示内容的符合条件下自动变化)。在这种情形下,上面讲到的方法就有巨大的积极影响、改进效果相当明显。如果您偶然出现一次要更新有几千子节点的情况,甚至像el.innerHTML += str或者el.innerHTML = ""这么简单的写法就可能带来灾难性的后果。

     事实胜于雄辩。为方便大家测试,阅网创建了一个测试页面,让大家可以立即、方便地进行测试innerHTML和上面整合的replaceHtml方法的性能差异,测试包含了不同数量的元素。测试的时间,请在一些主流浏览器进行测试,如常见的火狐、IE浏览器等,在不同的浏览器下的测试结果亲自做下对比。

    点此进进入测试页面,亲自体验不同浏览器下俩个方法的性能差异,点此开始测试把~!:)

1000 元素elements...
innerHTML (destroy only): 156ms
innerHTML (只创建元素): 15ms
innerHTML (destroy & create): 172ms
replaceHtml (destroy only): 0ms (速度很快)
replaceHtml (create only): 15ms (~ 速度相同)
replaceHtml (destroy & create): 15ms (11.5x 速度很快)

15000 元素elements...
innerHTML (只销毁元素): 14703ms
innerHTML (只创建元素): 250ms
innerHTML (销毁并创建元素): 14922ms
replaceHtml (只销毁元素): 31ms (474.3倍 速度很快)
replaceHtml (只创建元素): 250ms (~ 速度相同)
replaceHtml (销毁并创建元素): 297ms (50.2x 速度很快)

    俗话说:数字自己会说话,你懂的。在Safari浏览器中同样可以看到性能的大幅度提升。在Opera中速度对比replaceHtml比innerHTML依旧要快!在IE浏览器中,单纯使用innerHTML会比replaceHtml稍微快一点,但差异及其小,但replaceHtml使用IE的hacker功能(仅IE浏览器才会执行的代码)来避免这种细微的速度损失,使得在各种浏览器中的表现都更加彪悍。

    总结下,脚本编程中重在实践,在不断的测试中得到技能和经验的逐步提升,从而在前段开发中能够做到游刃有余,娴然漫步于互联网前段之路。

posted @ 2010-07-31 09:02  Tokyo  阅读(443)  评论(0编辑  收藏  举报