+1  A: 

You could just have two tbody elements in your primary table. One would be used for displaying, and the other for buffering. That way you could skip appending the other tbody and just remove display.none from the buffer to display it. My guess is that it could be a little faster and perhaps solve the glitch in IE.

An another method (trick?) for showing or hiding elements in a table I've learned is setting position to absolute on a row or tbody to hide it, instead of using display. That still hides it, but without altering (messing up) the table's layout. You could try using it to hide the buffer.

Generally, tables are one the most quirky elements there are, even in the modern browsers. Doing anything advanced with them usually leads to these little headaches, so good luck.

Reinis I.
Nice suggestions, but is it even legal to have two `tbody` elements? I was surprised to see this suggestion. And why would setting position to absolute hide a row? That doesn't seem to be working for me. (I used to consider my knowledge of HTML/CSS/Javascript pretty advanced before I started delving into this kind of stuff!)
Eli Courtwright
"Table rows may be grouped into a table head, table foot, and one or more table body sections" - http://www.w3.org/TR/html4/struct/tables.html#h-11.2.3
robertc
`tbody` would be a pretty useless element if you could only have one. Its point is grouping rows in a table. As for `position: absolute`, you use that in combination with, say, `visibility: hidden` and a negative `z-index` if using `display: none` creates problems. I'm fuzzy on the particulars, but I'm sure I've had such a situation more than once.
Reinis I.
+1  A: 

Have you got a width set on the table? It occurs to me that if you're generating the table while it's hidden it may not be picking up things like the current browser window width which it would normally use to set the width of a table, so it falls back to the maximum.

robertc
Yep, the width is set to 100%
Eli Courtwright
So if you set it to a specific number of pixels, rather than something which depends on the viewport size, do you still get the problem?
robertc
I didn't get a chance to find out, since bibinc's excellent advice above made the problem go away. But I wouldn't want a fixed=pixel width anyway since the content is dynamic and this needs to be viewed on different screen sizes and there's a lot of data so I really need the full width of the screen. Though if I do run into something like this again, I'll try setting a fixed-pixel width just to see whether that changes anything - thanks for the suggestion.
Eli Courtwright
+2  A: 

Can't say for sure without a test case, but in general:

  • Make sure you are using table-layout: fixed. IE is bad at guessing auto column widths, especially when there are colspans involved. It's also slow at guessing widths when there are many rows. Take this out of IE's hands by setting explicit sizes for each column with a fixed table layout.

  • Avoid appending rows to large tables. When you say children().appendTo() jQuery is still doing each append one at a time, which soon gets very slow indeed. The best thing you can do to speed up table manipulations is to set the whole lot in one go using innerHTML on the table's parent element. Of course preparing the HTML string can be annoying if you want to insert data (attribute values and content), since it has to be HTML-escaped. A workaround is to write all the rows at once with placeholder values, and then on a second pass fill in the real data through setting .data on Text nodes and so on. You will need to re-attach any event handlers you're putting on those buttons in this step too, unless you are using live.

  • I think by writing the rows with innerHTML you should be able to speed it up enough to get rid of the timeout-based partial updates (which would seem to have nasty potential race conditions). Of course the DOM-based alternative would be to only update the rows that have changed. When you are using fixed layout, since the widths don't depend on the content, you can break your table up into several tables after each other. They'll look like they're one table, but you can deal with each table separately, either writing its innerHTML in one go, or appending its rows without the DOM performance death you get from having thousands of rows in a single table.

bobince
Setting the `table-layout` to `fixed` made the problem go away. You have my eternal gratitude, and I'll keep your other advice in mind the next time I'm doing something like this.
Eli Courtwright