I identified why the $("<table />").append syntax is so extremely slow
in the sample page. It actually has nothing to do with being a 'second
DOM append' as was assumed. Here is what I learned from my testing...

This is the HTML mark-up for the tests:

<BODY>
        <DIV id="container"></DIV>
        <TABLE id="Table"></TABLE>
</BODY>

I generated the same 'html' var from Mike's test page - containing
2000 table-rows. The loop used is irrelevant to these tests because
the times shown below are for the DOM insertion *only*.

First, here is the original append-code from Mike's sample page...

$('#container').append(
   $('<table><tbody></tbody></table>').append(html)
);
// run-time: 7.5 sec

Note the extreme slowness of the insertion - over 7 seconds!

But by just *moving* the <tbody> tags, it becomes 20-times faster...

$('#container').append(
   $('<table></table>').append('<tbody>'+ html +'</tbody>')
);
// run-time: 0.36 sec

If we reduce it to a single command, it becomes 35-times faster...

$('#container').append(
    '<table><tbody>'+ html +'</tbody></table>'
);
// run-time: 0.24 sec

BTW, the speed is the same whether .html() or .append() is used.

If the existing table is used instead, we gain only a few ms.

$('#Table').append('<tbody>'+ html +'</tbody>');
// run-time: 0.22 sec

To see if it makes a difference appending to a table that's 'not
empty', I appended the same 2000 rows *10-times* (to keep the math
simple)

html = '<tbody>'+ html +'</tbody>';
$('#Table')
    .append( html )
    .append( html )
    .append( html )
    .append( html )
    .append( html )
    .append( html )
    .append( html )
    .append( html )
    .append( html )
    .append( html )
;
// run-time: 2.23 sec

The run-time to append 10-times is *exactly* 10-times as long as
appending the first time. This means it makes no difference whether
the table is 'empty' or already has content.

So, in my tests, there is *no benefit* to appending an entire table to
an empty container. You get identical performance (in IE7) by
appending the new rows to a table - as long as they are wrapped in a
tbody. If the rows are not inside a tbody, then they are appended one-
by-one! This is why the syntax used by Mike was so extremely slow. It
actually had nothing to do with appending 2 elements, which I knew
could not account for a 3000% difference!

I dynamically generate table rows A LOT. My current web-app appends a
7-row tbody as a 'new record'. But I do not use loops to generate
html. Instead I use a hidden 'template tbody' that I clone. This has
all the events for the form-fields pre-attached. All I do is rename
all the fields after cloning the template, and before appending it to
the target table. This method is much easier to read and update than a
hundred lines of html-generating script. Plus I actually use the same
mark-up to generate the existing records onLoad (via JSP), so there is
zero code duplication.

I wanted to identify the cause of the slow append in Mike's sample
because I never see this in my applications. Now that I understand
what was happening, I see that appending a tbody is actually extremely
efficient - in fact, even faster than writing a new table! This is
good news because I cannot regenerate the entire table each time - I
must append new rows/records to an existing table.

I thought I'd share these results because appending a tbody (or a
single row) provides many more options than writing an entire table.
And now I know there is no performance difference - at least not in
IE7.

Thanks to Mike for providing a starting points for these tests, in
addition to his loop-optimization tips.

/Kevin

Reply via email to