可能没有浏览器呛添加DOM节点的大量?节点、浏览器、DOM

2023-09-11 22:34:43 作者:千城墨白ぅ.

我有我的网站上的网页显示一张表,重新加载XML源数据每10秒(与XmlHtt prequest),然后更新表向用户展示数据的任何增加或清除。要做到这一点,JavaScript函数首先清除出表中的所有元素,然后添加一个新行每个数据单元。

I have a webpage on my site that displays a table, reloads the XML source data every 10 seconds (with an XmlHttpRequest), and then updates the table to show the user any additions or removals of the data. To do this, the JavaScript function first clears out all elements from the table and then adds a new row for each unit of data.

近日,笔者作战直通了一些内存泄漏在Internet Explorer由此引起DOM破坏,并创建code(其中大部分不得不与JavaScript对象和DOM对象,与JavaScript库之间的循环引用我们使用的是静静地保持对与新元素(...),直到页面被卸载)创建的每个JS对象。

Recently, I battled thru a number of memory leaks in Internet Explorer caused by this DOM destroy-and-create code (most of them having to do with circular references between JavaScript objects and DOM objects, and the JavaScript library we are using quietly keeping a reference to every JS object created with new Element(...) until the page is unloaded).

随着内存的问题解决了,我们现在已经发现了一种基于CPU的问题:当用户有大量的数据,查看(100+单位的数据,相当于100 < TR&GT ; 节点创建,加上所有表格单元的每一列),则处理捆绑的CPU直到Internet Explorer提示给用户:

With the memory problems solved, we've now uncovered a CPU-based problem: when the user has a large amount of data to view (100+ units of data, which equals 100 <tr> nodes to create, plus all of the table cells for each column), the process ties up the CPU until Internet Explorer prompts the user with:

停止运行此脚本?   此页上的脚本导致Internet Explorer中运行缓慢。   如果继续运行,您的计算机可能会变得   反应迟钝。

Stop running this script? A script on this page is causing Internet Explorer to run slowly. If it continues to run, your computer may become unresponsive.

看来,在运行行 - 小区创造code倍100+的数据块是什么原因造成的CPU使用率秒杀,功能采取太长(从IE浏览器的角度)来运行,因此引起IE来生成该警告的用户。我也注意到,虽然更新画面功能,运行时间达到了100行,IE不会重新绘制表格内容,直到函数完成(因为JS间preTER正在使用100%的CPU的时间段,我假设)。

It seems that running the row-and-cell-creation code times 100+ pieces of data is what is causing the CPU usage to spike, the function to take "too long" (from IE's perspective) to run, thus causing IE to generate this warning for the user. I've also noticed that while the "update screen" function runs for the 100 rows, IE does not re-render the table contents until the function completes (since the JS interpreter is using 100% CPU for that time period, I assume).

所以我的问题是:有没有办法在JavaScript来告诉浏览器JS暂停执行,并重新呈现DOM?如果不是,是否有处理产生大量的DOM节点的任何策略和的不是的具有浏览器呛?

So my question is: Is there any way in JavaScript to tell the browser to pause JS execution and re-render the DOM? If not, are there any strategies for handling creating large amounts of DOM nodes and not having the browser choke?

一种方法我能想到的将是异步处理的更新表的逻辑;也就是说,一旦Ajax的方法来重新加载XML数据完成后,将数据放入某种数组,然后设置一个功能(使用的setInterval())运行它将处理阵列的一个元件的时间。然而,这似乎是重新创建线程在JavaScript的环境中,这似乎是它可以得到非常复杂一点(即,如果其它的Ajax数据请求触发了,我还是重新创建表的DOM节点?等)

One method I can think of would be to handle the "update table" logic asynchronously; that is, once the Ajax method to reload the XML data is complete, put the data into some sort of array, and then set a function (using setInterval()) to run which will handle one element of the array at a time. However this seems a little bit like re-creating threading in a JavaScript environment, which seems like it could get very complicated (i.e. what if another Ajax data request fires while I'm still re-creating the table's DOM nodes?, etc.)

更新:只是想解释为什么我接受RoBurg的答案。在做一些测试,我发现,在我的框架新元素()方法(我用的 MooTools的)大约为2x在IE7传统使用document.createElement()慢。我跑了一个测试,以创造1000 &LT;跨度&GT; ,并将它们添加到&LT; D​​IV&GT; ,使用新元素()约需1800ms在IE7(虚拟PC上运行),传统的方法需要大约800毫秒。

update: Just wanted to explain why I'm accepting RoBurg's answer. In doing some testing, I've found that the new Element() method in my framework (I'm using mootools) is about 2x as slow as the traditional document.createElement() in IE7. I ran a test to create 1000 <spans> and add them to a <div>, using new Element() takes about 1800ms on IE7 (running on Virtual PC), the traditional method takes about 800ms.

我的测试中也发现一个更快的方法,至少在一个简单的测试,如我的:使用 DocumentFragments如由John Resig的的。在同一台机器与IE7上运行相同的测试用了247ms,一个 9X 改进从我原来的方法!

My test also revealed an even quicker method, at least for a simple test such as mine: using DocumentFragments as described by John Resig. Running the same test on the same machine with IE7 took 247ms, a 9x improvement from my original method!

推荐答案

100 &LT; TR&GT; 的是不是真的那么多...你还在使用该框架的新元素()?这可能是它的原因。

100 <tr>'s isn't really that much... are you still using that framework's new Element()? That might be the cause of it.

您应该测试新元素() VS 使用document.createElement() VS .innerHTML

You should test the speed of new Element() vs document.createElement() vs .innerHTML

也可以尝试内存中建立DOM树,然后将其追加到文件结尾。

Also try building the dom tree "in memory" then append it to the document at the end.

最后看,你不看.length过于频繁,或者类似的其他位和鲍勃。

Finally watch that you're not looking at .length too often, or other bits and bobs like that.