可以添加大量的DOM节点而不用浏览器窒息?

我的网站上有一个显示表格的网页,每隔10秒(使用XmlHttpRequest)重新加载XML源数据,然后更新表格以向用户显示数据的任何添加或删除。 为此,JavaScript函数首先清除表中的所有元素,然后为每个数据单元添加一个新行。

最近,我遇到了由这个DOM破坏和创建代码导致的Internet Explorer中的大量内存泄漏(其中大部分代码与JavaScript对象和DOM对象之间的循环引用有关,而且我们正在使用的JavaScript库安静地保留引用每个用new Element(...)创建的JS对象,直到页面被卸载)。

随着内存问题的解决,我们现在已经发现了一个基于CPU的问题:当用户有大量的数据可以查看时(100多个单位的数据,这等于100 <tr>节点创建,加上所有的表每个列的单元格),该过程将绑定CPU,直到Internet Explorer提示用户:

停止运行这个脚本?
此页上的脚本导致Internet Explorer运行缓慢。 如果它继续运行,您的计算机可能无响应。

看起来,运行行和单元格创建代码乘以100多条数据是导致CPU使用率激增的原因,从IE浏览器的角度来看运行时间太长,从而导致IE生成这个警告给用户。 我也注意到,虽然“更新屏幕”功能为100行运行,但IE不重新呈现表内容,直到函数完成(因为JS解释器在该时间段内使用100%的CPU,我假设) 。

所以我的问题是:JavaScript中有没有什么方法可以告诉浏览器暂停JS执行并重新渲染DOM? 如果没有,是否有处理创建大量DOM节点并且不让浏览器窒息的策略?

我能想到的一种方法是异步处理“更新表”逻辑; 也就是说,一旦重新加载XML数据的Ajax方法完成后,将数据放入某种数组中,然后设置一个函数(使用setInterval() )来运行,它将一次处理数组中的一个元素。 然而,这似乎有点像在JavaScript环境中重新创建线程,这似乎可能会变得非常复杂(例如,如果在我仍然重新创建表的DOM节点时另一个Ajax数据请求触发,等等)


更新 :只是想解释为什么我接受罗伯格的答案。 在做一些测试时,我发现我的框架中的new Element()方法(我使用mootools)大约是IE7中传统document.createElement()的2倍。 我运行一个测试来创建1000 <spans> <div>并将它们添加到<div> ,使用new Element()在IE7上运行大约1800毫秒(在Virtual PC上运行),传统方法需要大约800ms。

我的测试还揭示了一个更快的方法,至少对于像我这样的简单测试来说:使用John Resig描述的DocumentFragments。 在使用IE7的同一台计算机上运行相同的测试需要247ms,比原始方法提高了9倍!


100 <tr>是不是真的那么多...你还在使用该框架的new Element()吗? 这可能是它的原因。

您应该测试new Element() vs document.createElement() vs .innerHTML

也可以尝试在内存中构建dom树,然后将其附加到文档中。

最后要注意,你并不是经常看长短,或者是其他的那样。


在3000行表格的复杂数据行中,我遇到过类似的问题,所以有些代码不完全正确。 它如何在Firefox中运行? 你可以检查几个不同的浏览器。

你是否在任何地方绑定onPropertyChange? 这是一个非常危险的事件,它让我更早地造成了严重的头痛。 你是否在任何地方使用CSS选择器? 这些都是缓慢的,即。


您可以创建一个字符串表示并将其添加为节点的innerHTML

链接地址: http://www.djcxy.com/p/65273.html

上一篇: Possible to add large amount of DOM nodes without browser choking?

下一篇: many relationship with a 'reset' operation