通过 innerHTML 对 DOM 操作进行性能测试
Posted
技术标签:
【中文标题】通过 innerHTML 对 DOM 操作进行性能测试【英文标题】:performance test of DOM operations via innerHTML 【发布时间】:2011-03-08 07:00:26 【问题描述】:根据 *** 的精神(感谢@Bill the Lizard 澄清这一点),我想介绍一下所有前端 Web 开发人员都知道的小问题。
如何在编写 Dhtml、使用 innerHTML 或 DOM 操作时获得更好的 jscript 性能?
为了测试,我创建了带有“开始测试”按钮的单个 HTML 页面,该按钮运行 5000 次功能对,该功能是使用 innerHTML 思想或由 DOM 编写的。 (可上:http://codepad.org/HyiKRsNk)
为了避免比较 CPU 结果以百分比显示,一个函数如何比另一个更快。因此,如果您看到 (17%),则意味着 DOM 更快 innerHTML,如果(可能是后者)您看到 (-5%),则意味着 innerHTML 比 DOM 更快。 为避免内存爆炸的影响,每次调用都会在测试后立即创建和删除新的“测试区域”(没有遇到创建/删除时间)。 测试在 display:none div 下进行以避免翻转和滚动时性能下降我准备了3个测试(@tomdemuyt提出的最后一个)
为其创建新的 DIV 和子文本
删除部分DIV(为避免创建差异的影响,两个测试使用相同的方式创建测试div,但删除不同)
添加 onclick 事件处理程序
深度测试树的创建,测试创建<table><tbody><tr><td><span>text
构造。 DOM 测试使用对 createElement/appendChild 的顺序调用
与 (4) 类似,但创建了 2 行 <tr>
。 DOM 使用特殊的辅助函数来简化:
treeHelper("table",
treeHelper("tbody",
treeHelper("tr",
不同浏览器的测试结果如下。
所以亲爱的同事请提供:当 innerHTML 更快时显示一些测试,在尚未列出的浏览器上开始我的测试。
【问题讨论】:
有很多变化会影响性能。 1.)哪个浏览器,2.)您要插入哪些元素,3.)要插入的元素/DOMString 的数量等。特别是旧版本的 IE 存在主要的字符串连接性能问题,因此即使 .innerHTML 插入可能更快与构建 DOM 相比,由于字符串 concat 问题,IE 会更慢。 @scunliffe - 根本没有连接!仅附有完整的字符串,请在下面查看我的答案,以下是 4 个浏览器的列表。如果您能提供更多 - 那就太好了! true 在这个测试中它可能只是一个简单的字符串,但实际上你将构建各种元素集合(例如,整个表格,包装在一个表单中,在一个 div 中放入页面的某个地方)。您还需要注意,您无法在 IE 中设置某些 .innerHTML 值,反之亦然,在 IE 中的标准 DOM 操作中您无法执行许多操作。像 jQuery 这样的 JS 库在这里真的很有帮助,因为它们可以将你从这些浏览器的差异中分离出来。 @scunliffe 抱歉,例如,无法理解,“...实际上您将构建各种元素集合...”这如何影响基准测试什么是更快的 DOM 或 innerHTML?您能否提供描述您想法的测试用例或场景,我会将其放入所有测试集合中。 【参考方案1】:基于原始问题的 cmets,我在此处添加了一个答案,详细说明了为什么直接向上 .innerHTML
到 DOM manipulation
比较很难简明地评估。
基本上有几个主要问题:
-
浏览器错误和缺少实现
内容差异(在 A 情况下效果更好,在 B 情况下可能不会更好)
时间问题(javascript 无法控制或洞察浏览器何时决定执行 GC(垃圾收集)或运行其他线程/活动
1.) 特别是 IE(6,7 和较小程度的 8)有一堆浏览器错误,导致对所有代码场景进行全面测试。 (IE 有错误,无法在 select
、table
、thead
、tbody
、tfoot
、tr
上设置 .innerHTML
,内容所在的空元素设置为 auto高度超过 1 个“行”,pre
内容包含重要空白的元素等)
2.) 添加的子节点的数量、类型(顺序)和深度将改变操作的性能。例如。通过添加 table 标签来添加表格,然后是 tbody,然后是 tr,然后是 td,然后是 content,而不是单独构建它并将其转储到页面中会改变性能。
3.) 浏览器控制它何时执行 GC(这会在浏览器进行清理时减慢浏览器的速度)。同样,浏览器扩展程序或另一个选项卡中的 AJAX 调用,IE8 中的 Web 切片会轮询服务器以获取将影响当前页面执行方式的更新。
因此,如果您想对此进行全面测试,则需要测试几种不同的 HTML 子结构组合,我非常希望结果会有所不同。
我在家里有一些针对这类事情的旧测试,我会挖掘并添加到这个答案中以进行更多涉及的测试。
【讨论】:
根据您的建议,刚刚添加了 +2 测试以深入了解树的性能【参考方案2】:歌剧(10.54):
Test Result
1.insert new element and text 30.00%
2.removeChild vs innerHTML='' 66.67%
3.set event handler 245.45%
4.test in depth of tree linear -62.16%
5.test in depth of tree (using helpr) -67.10%
Chrome (5.0.375.70):
Test Result
1.insert new element and text 318.18%
2.removeChild vs innerHTML='' 53.85%
3.set event handler 150.00%
4.test in depth of tree linear 41.67%
5.test in depth of tree (using helpr) -33.03%
火狐(3.6.4):
Test Result
1.insert new element and text 76.17%
2.removeChild vs innerHTML='' 50.56%
3.set event handler 1097.44%
4.test in depth of tree linear 32.94%
5.test in depth of tree (using helpr) 9.66%
IE(8):
Test Result
1.insert new element and text 46.92%
2.removeChild vs innerHTML='' 26.34%
3.set event handler 936.17%
4.test in depth of tree linear -35.42%
5.test in depth of tree (using helpr) -67.26%
已编辑(1): 为每个浏览器添加 2 行深度构建树测试(树线性深度测试,树深度测试(使用帮助器))。发现大多数浏览器不喜欢堆栈分配值,因为线性 appendChild, appendChild... 比在 treeHelper('table', treeHelper('tbody', ....
【讨论】:
以上是关于通过 innerHTML 对 DOM 操作进行性能测试的主要内容,如果未能解决你的问题,请参考以下文章