Internet Explorer slows down the display of tables generated using JavaScript

I am working on a page in a web application with a large table. 12 columns and up to 300 rows in some cases. I find it hard to get a table for rendering in Internet Explorer. I reproduced my difficulties in this bit of test code:

http://jsfiddle.net/dSFz5/

Some tests with IE9 on the Intel Core Core Q8200 with 4 GB of RAM:
50 rows, 12 columns: 432ms
100 rows, 12 columns: 1023ms
200 rows, 12 columns: 2701ms
400 rows, 12 columns: 8107ms
800 rows, 12 columns: 24619ms

Exponentially bad.

I managed to dig up some code that makes the same test pattern MUCH faster in Internet Explorer, but since I use mustache.js templates to render my cells and rows (keeping all the HTML markup from my JavaScript), I can’t use these DOM methods:

http://jsfiddle.net/bgzLG/

Test results:
50 rows, 12 columns: 37ms
100 rows, 12 columns: 72 ms
200 rows, 12 columns: 146ms
400 rows, 12 columns: 324ms
800 rows, 12 columns: 566ms

I cannot build a table block with a block, as in the second example, because with client templates I need to enter the HTML strings returned by the mustache. If you start embedding .innerHTML in there, tank tanks again.

Can someone recommend a way to build a table in a more efficient way compatible with using client templates?

Markup is one way to solve this problem, but I would like to solve the problem myself.

Any suggestions that were highly appreciated!

+4
source share
3 answers

First, I would suggest separating row creation from actual table creation, because it creates overhead in terms of rendering time. Then you should try to create the whole table before adding it to the body in order to minimize the number of repaints / reflows. Finally, I would suggest joining the array in IE, because string concatenation in this browser repeatedly allocates large and large blocks of memory for each copy. When you use array combining, the browser allocates enough memory to store the entire string.

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');​ 

Using this method, I get the following results in IE9:

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

I am sure that we could optimize it further, but this should be enough for up to 300 lines (~ 30 ms), which was what you said about your goal. He also holds it under the holy grail of less than 50 ms for any interaction with the user interface.

+5
source

using this:

 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); 

About 130 ms shaved. This creates a table in memory before adding it to the DOM.

Here are my tests:

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

 And your original:

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

+2
source

I would say that the templates here are simply not suitable due to performance reasons. And it makes sense to build a table using DOM manipulations with all rows in the first place and only then add it. This is of great importance.

You can also try something like jqGrid: it processes a huge number of lines, and only visible lines are displayed on the screen in html (virtual list).

0
source

Source: https://habr.com/ru/post/1397730/


All Articles