IE8的DOM内存问题(插入大量JSON数据)

时间:2010-03-31 17:24:37

标签: javascript jquery dom memory-management internet-explorer-8

我正在开发一个小型Web实用程序,它显示某些数据库表中的一些数据。

我在FF,Safari,Chrome上运行的实用程序运行良好......但是IE8上的内存管理非常糟糕。最大的JSON请求将返回信息,以在浏览器中的表中创建大约5,000行(表中的3列)。

我正在使用jQuery来获取数据(通过getJSON)。要删除旧/现有表,我只是做$('#my_table_tbody').empty()。要在表中添加新信息,在getJSON回调中,我只是将我正在创建的每个表行附加到变量,然后一旦我拥有它们,我使用$('#my_table_tbody').append(myVar)将其添加到现有的。我不会在创建表行时添加它们,因为这似乎比只是一次添加它们要慢得多。

有没有人对尝试向DOM添加数千行数据的人应该做什么有任何建议?我想远离分页,但我想知道我是否没有选择。

更新1 所以这是我在innerHTML建议之后尝试的代码:

/* Assuming a div called 'main_area' holds the table */
document.getElementById('main_area').innerHTML = '';

$.getJSON("my_server", {my: JSON, args: are, in: here}, function(j) {
   var mylength = j.length;
   var k =0;
   var tmpText = '';
   tmpText += /* Add the table, thead stuff, and tbody tags here */;
   for (k = mylength - 1; k >= 0; k--)
   {
      /* stack overflow wont let me type greater than & less than signs here, so just assume that they are there. */
      tmpText += 'tr class="' + j[k].row_class . '"   td class="col1_class" ' + j[k].col1 + ' /td td class="col2_class" ' + j[k].col2 + ' /td  td class="col3_class" ' + j[k].col3 + ' /td /tr';
   }

   document.getElementById('main_area').innerHTML = tmpText;
}

这就是它的要点。我也尝试过使用$ .get请求,让服务器发送格式化的HTML,然后在innerHTML中设置(即document.getElementById('main_area').innerHTML = j;)。

感谢所有回复。我很遗憾你们都愿意帮忙。

5 个答案:

答案 0 :(得分:2)

     var tmpText = [];
    for (k = mylength - 1; k >= 0; k--)
       {
          /* stack overflow wont let me type greater than & less than signs here, so just assume that they are there. */
    tmpText.push('anything you want')
          tmpText.push( 'tr class="' + j[k].row_class . '"   td class="col1_class" ' + j[k].col1 + ' /td td class="col2_class" ' + j[k].col2 + ' /td  td class="col3_class" ' + j[k].col3 + ' /td /tr';)
       }
    $('#main_area').html(tmpText.join(''))

    }

你不需要document.getElementById('main_area').innerHTML = '';

这个方法是推入数组,然后加入并使用jquery html函数进行更新。这是我所知道的最快的方法。对不起这里的格式 - 这是我的第一篇文章,我想我会在这里回复一下stackoverflow。

答案 1 :(得分:0)

要让IE快速响应,您应该将表行创建为HTML的字符串表示形式,将它们附加到字符串变量,然后将结果添加到表格中。

myTable.myTbody.innerHTML = allThoseRowsAsAString;

这不是内存问题:5,000行应该是微不足道的。这远远不到一兆字节。

答案 2 :(得分:0)

Robusto认为innerHTML赋值是一种更好的方法。 IE糟透了动态DOM创建

为什么不使用jsp在服务器上形成innerHTML,并通过ajax一次性将其流回。它肯定会加快速度,从你的javascript中删除复杂性并将标记创建委托给它适当的位置。

答案 3 :(得分:0)

正如Plodder所说,IE在使用DOM时存在很大问题。 jQuery最佳实践建议在一个简单的字符串上创建代码,并在容器中只附加一次。

除此之外,我最近对于一个包含5,000个数据记录的等级数据有类似的问题。我问自己:用户是否确实需要在给定时刻提供所有可用信息?然后我意识到我能做的最好只是提供“第一块数据”,然后根据用户需求插入更多数据。

最后,只有一个好工具:Dynatrace Ajax(找到javascript函数需要花费更多时间来操作)

答案 4 :(得分:0)

由于您正在处理数千个数据行,因此我不会调用$('#my_table_tbody').empty()并使用新的DOM元素添加新数据。相反,我会关注Object Pool Pattern。因此,您可以重复使用现有的tr而不是丢弃所有tr,而只需填充新数据。

如果新数据集的行数少于前一行,则从DOM中删除其余行,但在某个池中保留对它们的引用,以便垃圾收集器不会销毁它们。如果您的新数据集更大 - 只需按需创建新的数据集。

您可以查看来源YUI DataTablehere's的实施情况。 IIRC他们使用这种方法来加快渲染时间。