IE - Oh how I loathe thee…
I’ve spent the past couple weeks trying everything I can think of to improve javascript performance in IE. My tableFilter plugin runs incredibly fast in Firefox, but it’s a pig in IE. I’ve been through all of the MSDN “how to improve performance in IE” posts, and every other board I can find, and couldn’t find a resolution.
It turns out that the problem appears to be IE’s handling of CSS. While I’m parsing table columns I add a row and column classname to each cell so plugins can take advantage of them. My columnStyles plugin uses it to automatically right-align numeric and date columns, for example. It appears that when you add a class name on the fly, IE tries to look the class up in the stylesheet and apply the styles immediately (or something). This happens even if the class doesn’t exist, which it doesn’t initially. I add all of the classes for columnStyle after the parsing is done (I have to, because I need to know the column’s dataType).
So the solution to this, at least for smaller table, was to create a CSS rule that does display:none; before parsing the columns then display:”"; when finished. On my smaller table demo this alone dropped parsing time from 550ms per column to around 50ms which some might consider an improvement (Firefox does it in 8ms). Unfortunately it doesn’t make a difference on the large table - I don’t think IE has enough time to recover from the CSS rule change on a larger table before it starts parsing, so it doesn’t recognize the non-displayed cells. I tried adding an alert so I could pause it, a delay function that wouldn’t continue until the last cell of the last row was display:none, nothing worked. On the delay function specifically it looked like the currentStyle for the cell was updated immediately, but the actual changes hadn’t taken place yet. I yearn for a CSSChangeComplete event… I was forced to give up and not allow the plugin to run on IE with large tables.
Very frustrating, but hopefully this is good information for someone.
Trackbacks
Use this link to trackback from your own site.
You may have tried this already, but what about cloning the table, doing all the manipulations on the cloned copy and replacing the original with the clone when the processing is done? Does ie do the stupid css lookup on elements that aren’t attached to the dom?
It might be worth trying, though the overhead from cloning and reattaching an entire table might be just as bad. You gave me an interesting idea though - I wonder what would happen if I created a brand new td, applied the classnames and contents, then inserted the new one in the old ones place… I appreciate the lead
Follow-up: I tried using cloneNode and replaceChild as well as createElement removeChild and insertBefore/appendChild with no improvement. The first method was faster than the second, but IE still chokes on the large table. I also tried both methods without the td display:none, and it reverted to the 550MS per column behavior. This tells us that IE tries to apply CSS rules (that don’t exist) to nodes that don’t exist in the DOM. I guess that should be expected since it makes absolutely no sense.
On a whim, I also tried creating the css classes in my stylesheet so they did exist to see if that would help - it doesn’t.
Good thought anyway!
I will probably regret suggesting this — since it’s usually seen as a terrible, horrible, not so good idea — but have you considered using innerHTML instead of DOM? The reason I mention it is:
http://www.quirksmode.org/dom/innerhtml.html
I appreciate the suggestion. Unfortunately, the issue is purely with adding a classname to an element. IE just can’t do it on the fly without choking. The more I work with IE the more stunned I am by the terrible design. Who would have thought that hiding the table cells before adding classnames would improve performance
(at least in smaller tables…)
is it possible to make the the table to display hiearchy of the data, lets say master table and details table
tableFilter wasn’t designed to link tables like that, but I’m planning on adding some ajax functionality that could include some hooks for that kind of thing. I’ll give it more thought.