2012-02-22 58 views
4

我正在使用大型表格在Web应用程序的页面上工作。在某些情况下,可以使用12列和多达300行。我很难让表格在Internet Explorer中快速呈现。我复制我的困难在此位的测试代码:Internet Explorer缓慢渲染通过JavaScript生成的表格

http://jsfiddle.net/dSFz5/

上英特尔四核Q8200 4GB内存与IE9的一些基准测试:
50行,12列:432ms
100行, 12列:1023ms
200行,12列:2701ms
400行,12列:8107ms
800行,12列:24619ms

指数级差。

我设法挖掘了一些代码,这些代码在Internet Explorer中显示的速度相当快,但由于我使用了mustache.js模板来呈现单元格和行(保留所有HTML标记超出我的JavaScript),我不能够使用这些DOM方法:

http://jsfiddle.net/bgzLG/

基准测试结果:
50行,12列:仅为37微秒
100行,12列:72ms的
200行,12列:146ms
4 00行,12列:324ms
800行,12列:566ms

我无法构造块表块像在第二示例中,由于与客户端模板我需要注入HTML的串由胡子回来。如果你开始粘贴.innerHTML的内容,那么表演坦克会再次出现。

任何人都可以推荐一种方法来建立一个更高效的方式与客户端模板的使用兼容吗?

分页是处理此问题的一种方法,但我想自己解决问题。

任何建议非常感谢!

+0

我认为这是DOM遍历,你在循环的每一次迭代中做的事情,然后是DOM操作12次,这是在杀死它。尽可能少地触摸DOM。做任何可以处理的东西,然后将其添加到DOM。 – 2012-02-22 06:45:22

回答

5

首先,我建议从实际创建表分离出弦的创作,因为它的问候渲染时间造成的开销。接下来,您应该尝试在将其附加到主体之前创建整个表格,以最大限度地减少重新绘制/重新焊接的数量。最后,我建议在IE中加入一个数组,因为该浏览器中的字符串连接会为每个副本重复分配更大和更大的内存块。当你使用数组连接时,浏览器只分配足够的内存来保存整个字符串。

var strings = [], 
    table = ['<table>'], 
    i, j; 

for (i = 0; i < 1000; i += 1) { 
    strings[i] = []; 

    for (j = 0; j < 12; j += 1) { 
     strings[i][j] = randomString(); 
    }   
} 

var start = new Date().getTime(); 

for (i = 0; i < 1000; i += 1) { 
    table.push('<tr>'); 

    for (j = 0; j < 12; j += 1) { 
     table.push('<td>', strings[i][j], '</td>'); 
    } 

    table.push('</tr>'); 
} 

table.push('</table>'); 

$('body').append(table.join('')); 

var end = new Date().getTime(); 
var time = end - start; 
alert('Execution time: ' + time + 'ms');​ 

使用这种方法,我得到如下结果在IE9:

100 rows is ~9ms 
200 rows is ~19ms 
500 rows is ~51ms 
1000 rows is ~119ms 
5000 rows is ~526ms 

我敢肯定,我们可以进一步优化,但是这应该是足够足够容纳300行(〜30毫秒),这就是你说你的目标是。对于任何用户界面交互,它也保持在低于50ms的圣杯基准下。

+0

你需要50个声望来评论你不属于你的帖子。如果你不断回答问题,你应该可以在几个小时内得到它:) – 2012-02-22 07:20:56

+0

看起来好像我的评论消失了。 :( 感谢您的支持,虽然我已经更新了我的答案,包括基准测试和一些解释,希望OP能看到它 – 2012-02-22 08:06:28

+0

这真是太棒了为了使您的解决方案适用于我的代码,我必须编写一个函数类添加到DOM后收集和绑定元素的事件(通过元素ID),但最终不会使代码复杂化,并且运行速度非常快,对于IE6和IE7用户,这是您唯一的方式可以在浏览器端创建具有事件处理的大型表格,IE6和IE7无法在内存中处理构建大型DOM元素。 – 2012-02-29 18:00:31

0

我会说模板在这里不适合,因为性能的原因。而且,首先使用所有行对DOM进行操作来构建表,然后才可以追加它。它有很大的不同。

你也可以尝试类似jqGrid的东西:它处理大量的行,而只有可见的行在html(虚拟列表)中呈现在屏幕上。

2

使用此:

var table = $('<table></table>'); 

for (var a=0; a<200; a++) { 


    var tr = $('<tr></tr>');  
    for (var b=0; b<12; b++) { 

     tr.append('<td>'+randomString()+'</td>');   

    } 

table.append(tr); 
} 

$('body').append(table); 

刮了约130MS。在将其添加到DOM之前,这是在内存中构建表。

这里是我的基准:

 
100 - 346 
200 - 670 
500 - 2037 
1000 - 4272 
2000 - 10502 

And your original: 

100 - 408 
200 - 898 
500 - 2987 
1000 - 10202 
2000 - 41305 

+0

Jquery是非常酷的东西:)越少触摸DOM,越好。祝你好运! – 2012-02-22 07:07:46

相关问题