Skip to content

Loading…

appendToTable is very slow in IE9+...any way to speed up the script? #72

Closed
camartinez1229 opened this Issue · 20 comments

3 participants

@camartinez1229

Hello, Mottie. I've been testing your fork of tablesorter on a personal site I'm developing locally, and have been pleased with the results--well, mostly.

On a table of 11 columns and 700+ rows (consisting of stats on songs I have charted on a weekly top 50), with the pager plugin enabled, I get results like these:

Firefox 12: Builds initial cache in ~200ms, sorts digit columns in <10ms, shortdate columns in <20ms, one pure text column in ~40ms, and one text column with embedded markup (hereafter referred to as "markup") in ~200ms. The table gets rebuilt after each sort in ~20ms (Overall blazing fast!)

Firefox 3.6: Builds initial cache in ~300ms, sorts digit columns in ~25ms, shortdate columns in ~50ms, the pure text column in ~100ms, and the markup column in ~2000ms (oddly slower). Table rebuilds each time in ~90ms. (With the exception of the markup column, still very fast, but am not worried about it, since I'm not planning on supporting FF 3.5/3.6 for long.)

Now, to speed things along a bit, I'll just summarize the results of some other browsers:

Chrome 18 and Safari 5.1: Speeds slightly slower than Firefox, but we're only talking differences of less than 100ms, and often less than ~50ms. Performance feels just as snappy.

Opera 11.6: I did notice unusually slower initial cache build times (~6000ms), slower sorts (~100-250ms depending on column type), and slower rebuilds (~500-1000ms). Opera definitely feels slower, but still performs acceptably, in my opinion.

But now, here comes the wall I've run in to:

IE9: It builds the initial cache in ~200ms. That is perfectly okay. It even sorts columns quite fast (<10ms for the date and digit columns and ~50ms for the text column), except for the markup column, which comes in at a much slower ~900ms. However, rebuilds absolutely destroy performance: 2500ms on average for each sort! During which, the table appears frozen... I figured I could at least give visual feedback by showing an overlay with "Please Wait" during the sort phase, as you demoed, but for some reason, IE does not show it (it will show in every other browser, though.) In profiling the script, I've ruled that the appendToTable function is the bottleneck, specifically the appendChild in the loop iterating over all the rows. I guess IE is just horribly slow at DOM manipulation...? Things were no better when I tested in the latest available preview of IE10 for Windows 7 (more recent previews are only available on Win 8 previews currently, which I have no desire to install so far.)

However! IE's JS performance really insults me, in that IE8 is faster! Huh? Check out my numbers:

IE8: It builds the initial cache in ~900ms. Okay, so that's actually slower. And, sort speeds compare to IE9, except for the text/markup columns, which are about 2/3 to 3/4 the speed of IE9's sorts. However, table rebuilds are significantly faster: 200-400ms on average for each sort--IE8 is up to 10 times faster than IE9!

IE7: I tested this just for kicks, even though I'm not supporting IE7 or lower on my site. It builds the initial cache in ~1600ms, sorts columns at comparable speeds to IE8, but rebuilds the table significantly slower than IE8, at ~800-900ms. That's still up to 3 times faster than IE9!

I've tried so much to debug IE9's abysmal performance. Knowing that I have IE9 apply more CSS to my tables than IE8, such as box-shadow, border-radius, and SVG background gradients, I experimented with disabling all CSS. This resulted in average savings of 1000ms for each table rebuild, but that is not enough, as that leaves the times at a still way-too-slow ~1500ms. I also ran the same experiment in IE8, and saw its rebuild times decrease a bit to ~180-250ms. While the savings, especially in IE9, do help, there's no way I'd leave my tables unstyled...especially when all the other better browsers perform admirably with the CSS included.

I've also tried streamlining the appendToTable function on my own...but, I'm no JS expert. Knowing that my table will always have only one tbody, I moved script out of the loop that iterates over the tbodies, and then removed the loop. And, knowing I have no need for cssinfoblock, I removed the check for that...so far, none of that has been enough, though. In the loop for (i = 0; i < totalRows; i++), f.appendChild(r[pos][j]); is the bottleneck I've zeroed in on. I've been trying to figure out some way to do that appending outside the loop, to reduce the calls to appendChild from 700+ down to 1, theoretically leading to the speed improvement I seek. However, I'm at the end of my current JS knowledge. Anything I've tried keeps resulting in DOM exceptions... Is it possible to append an array of objects to the DOM? I know currently, table.tBodies[k].appendChild(f); appends the created document fragment of rows, to the tbody. In its place, I've been trying to come up with a way to do something like table.tBodies[0].appendChild(r[*entire pos array*][*tablerow element in each part of pos array*]); and remove f.appendChild(r[pos][j]);, but I'm not getting anywhere. Maybe I have the wrong approach? Like I said, I'm not an expert in JS... Do you have any suggestions on how to solve IE9's slowness?

If you want, I can gather together my table and relevant CSS, if it helps. However, in your triggers sortEnd and sortStart demo page, you can witness slowdowns proportional to mine with my table. On my machine, FF, Chrome, Safari, and Opera all tend to sort the columns in .1 seconds or less (sometimes taking a little longer on the first two text columns), while IE9 is never faster than .1 second, and will take .8-1.2 seconds on those text columns. IE8 stays under 1 second on those two columns, but still comes up slow at over .8 seconds. Finally, as a real head-scratcher, IE7 stays under .5 seconds on those two columns, and even comes in at under .2 seconds for the second column (comparable to the rest of the columns). I just don't get this, haha.

Please let me know if there's any way you can help me. And again, if I can help too, like by giving you my testing code, I'd be glad to...thanks in advance!

@Mottie
Owner

I'm not sure if you're using the latest version but I recently changed both the main tablesorter plugin and the pager plugin to start using document fragments to speed up the table rendering process. So using appendChild() on a document fragment should be much faster than appending them directly to the DOM. Please make sure you're using this version.

If you are using the latest version, then yeah, maybe sending me the files you are using will help me figure out what's going on with IE9.

@camartinez1229

Thank you for the response. I'm using the most recent version I saw, 2.3.2, and it does incorporate the document fragment. I'm not sure if there's any way of sending files to you through here, but I have uploaded to my SkyDrive, a 7Z archive with my table in a reduced html page from my Wordpress blog, and the supporting CSS/JS I currently load. You may download it at https://skydrive.live.com/redir.aspx?cid=2d523830bfdcb28e&resid=2D523830BFDCB28E!138&parid=2D523830BFDCB28E!132&authkey=!AH5dGubxkaFBKpw. Let me know if this works for you, or if there's a better way for me to send my files. Thank you.

Update: I re-uploaded my archive just now because I realized I had left a file with an incorrect name. Silly me...

@Mottie
Owner

I took a quick look at the file you shared last night and it was really slow, even in Chrome. I think it might be due to all of the custom fonts, most of which weren't found so that might have been part of the issue, on top of all of the data that needed to be processed.

When I have more time today, I'll see how it does with basic styling and then test it in IE9.

Have you considered setting up the table to work with ajax?

@camartinez1229

Sorry about that. I guess I should've either included the fonts, or removed the references to them in the CSS. Interestingly, however, I just retested my test page (which does not have the fonts available), and it ran speedily for me, ~100ms to build the initial cache, and ~70ms to rebuild the table after sorts. Could it be a difference in our machines? I'm running on Windows 7 64-bit, with a Core i7-2630QM at 2 GHz...

I haven't even finished my table's appearance in Webkit, if you may have noticed--the last column may appear disproportionately wide, ha.

Anyway...as for ajax. No, I haven't gotten that far yet. It'd be something new for me to learn and to have to setup, and I have reservations about it, which discourages me from doing so. My impression is that if you load, say only the first 25 rows via ajax (I generate my table having the song titles sorted A-Z, so it looks sorted even without using sorting or without JS enabled), but then sort any column, say the song titles to Z-A, then all the data would have to get loaded and processed, anyway, right? Table rebuilds are what destroy IE9's performance. Please correct me if I'm wrong...I'd be up for considering AJAX if it really may help.

@camartinez1229

Oh yeah, as for basic styling in IE9...I did test my page with all CSS disabled in IE9. While it shaves off a fair amount of time, about ~1000ms per rebuild, it's still extremely slow at ~1500ms. So, I don't think that's the main issue, especially since all other current browsers do just fine with the CSS, even IE8.

@Mottie
Owner

Hmm, so I think the problem is actually the natural sort that I recently added. It uses a few functions like replace, split, match, parseInt and parseFloat which when called repeatedly seems to really slow down IE. I think the easiest, maybe not the best, solution would be to just replace the text sorter when IE is running. This is how it can be done:

$(function(){

    $.tablesorter.addParser({
        id:'peak',
        is:function(s){return false;},
        format:function(s){
            var strall = s.split('-'),
                stra = parseInt(strall[1], 10),
                strb = strall[0];
            return strb + (100 - stra);
        },
        type:'numeric'
    });

    // Add a class to the body to indicate IE is running.
    $('<!--[if IE]><script>jQuery("body").addClass("is-ie");</script><![endif]-->').appendTo('body').remove();

    var options = {
        debug: true,
        headers: {
            0: {sorter:false},
            1: {sorter:'text'},
            4: {sorter:'peak'}
        },
        cssAsc: 'hu',
        cssDesc: 'hd',
        cssHeader: 'he'
    };

    if ($('body').hasClass('is-ie')) {
        // add very basic text sorter if IE is running
        options.textSorter = function(a, b, table, column){
            // this is the original sort method from tablesorter 2.0.5b
            return ((a < b) ? -1 : ((a > b) ? 1 : 0));
        }
    }

    $('table')
        .tablesorter(options)
        .bind("sortStart",function(){
            $("#overlay").show();
        })
        .bind("sortEnd",function(){
            $("tbody th").each(function(i){
                $(this).html(i + 1);
            });
            $("#overlay").hide();
        })
        .tablesorterPager({
            container: $(".pager")
        });
    });
@camartinez1229

I tried implementing your suggestion...with it, I only saw savings of about 200ms per rebuild, and still quite a noticeable lag on each rebuild. But, with your suggestion in mind, I then additionally tried substituting in the digit and shortdate parsers from 2.0.5b. That didn't help much either, and in fact, I began getting wild variations in the rebuild times--they'd occasionally be under 2000ms, while at times, they'd jump to over 6000ms...crazy.

Soon after, I thought of starting from scratch with 2.0.5b...surprisingly, that's fixed my issues with IE. Both IE8 and IE9 complete sorts and rebuilds in under 100ms, often even under 50ms. Wow. Incidentally, when I was first implementing tablesorter, I began with that version, but then upgraded to your update soon after I discovered it, because I figured newer would be better. I guess not always, though, if IE is just gonna choke on things.

Anyway, I've run into another issue after downgrading to 2.0.5b. If I use the old pager plugin, I can't properly preserve my row numbers. For example, with a page size of 25 rows, I want page 2 to always be numbered 26-50, no matter what sort is active. This is possible with your plugin, because of the hiderows function that's executed when removeRows is false. However, I'm not sure if that functionality can be ported back to the old plugin (haven't tried yet, as I write this). So, I've been trying to work with your updated pager plugin instead. Well, with that, I run into a problem that you do mention in your docs--sorting completely breaks when removeRows is false. Do you know why that happens? I've been trying to figure that out with no success so far. If I set it to true instead, then my numbering gets messed up--each page will only be numbered 1-25, which I don't want.

@Mottie
Owner

Hmmm, maybe it would be better to figure out why there is such a difference between the current version and 2.0.5b.

I'd have to dig through the change log to remember what I added to the plugin core to make the removeRows option work, but I'd rather find the reason for the difference.

@camartinez1229

I tested the earliest version I found on here, 2.0.6, and even then, IE9 was still as slow with the rebuilds as 2.3.2 is. I even attempted a comparison of 2.0.5 and 2.0.6 in Notepad++, using a feature to highlight differences between the files, but determined it would take me far too long to go through that, as nearly every line had something highlighted (perhaps mostly due to space formatting).

I also discovered that you added removeRows in 2.0.21. I tested that version as well. Sure, the paging works the way I want, but IE9's performance is still abysmal.

I'm really frustrated with this. I think I just need to set this aside for a while, or maybe just look at it with fresh eyes tomorrow (or later in the week)--I've got far more other work to do in preparing my site, anyway, and hate that this issue has hung me up for a few days already.

Please let me know if you think of any other ways to try to fix IE9's performance. Thank you.

@camartinez1229

I've finally achieved a breakthrough!!!!!111!!!1 Haha.

So, I ultimately realized that IE will apparently never see decent performance if removeRows is false. Having it set to true, for whatever reason, seems to be the only way to get <100ms sort and rebuild times. But then, what about my row numbering issue? Well, I got that fixed! I modified my row numbering function, and the moveToPage function. Here is the minified pager with my mods:

(function(d){d.extend({tablesorterPager:new function(){var l=function(a){a.updateArrows&&(a.container.removeClass(a.cssDisabled),d(a.cssFirst+","+a.cssPrev+","+a.cssNext+","+a.cssLast,a.container).removeClass(a.cssDisabled),a.page===0?d(a.cssFirst+","+a.cssPrev,a.container).addClass(a.cssDisabled):a.page===a.totalPages-1&&d(a.cssNext+","+a.cssLast,a.container).addClass(a.cssDisabled),a.totalRows<a.size&&a.container.addClass(a.cssDisabled))},o=function(a,b){b.startRow=b.size*b.page+1;b.endRow=Math.min(b.totalRows, b.size*(b.page+1));var c=d(b.cssPageDisplay,b.container),e=b.output.replace(/\{(page|totalPages|startRow|endRow|totalRows)\}/gi,function(a){return{"{page}":b.page+1,"{totalPages}":b.totalPages,"{startRow}":b.startRow,"{endRow}":b.endRow,"{totalRows}":b.totalRows}[a]});c[0].tagName==="INPUT"?c.val(e):c.html(e);l(b);b.container.show();d(a).trigger("pagerComplete",b)},m=function(a){var b=a.config,a=d(a);if(!b.pagerPositionSet&&b.positionFixed)a.offset&&b.container.css({top:a.offset().top+a.height()+ "px",position:"absolute"}),b.pagerPositionSet=!0},k=function(a,b){var c,e=d("tr",a.tBodies[0]),h=e.length,j=b.page*b.size,f=j+b.size;f>h&&(f=h);for(c=0;c<h;c++)e[c].style.display=c>=j&&c<f?"":"none"},i=function(a,b){var c,e,h,j,f=a.config,g=b.length;c=f.page*f.size;var i=c+f.size;d(a).trigger("pagerChange",f);if(f.removeRows){if(i>b.length)i=b.length;j=d(a.tBodies[0]);for(d.tablesorter.clearTableBody(a);c<i;c++){h=b[c];g=h.length;for(e=0;e<g;e++)j[0].appendChild(h[e])}}else k(a,f);m(a,j);d(a).trigger("applyWidgets"); f.page>=f.totalPages&&n(a);o(a,f)},

g=function(a){var b=a.config;if(b.page<0||b.page>b.totalPages-1)b.page=0;i(a,b.rowsCopy)

    /*
    Fix absymal slowness in IE9+, and speed up the slightly sluggish IE8 and Opera. 
    Basically fakes effect of "removeRows:false" even when it's actually set to true, 
    by calculating correct row numbers based on current page.
    */
    if ($.browser.msie || $.browser.opera) 
    {var $ths = $("tbody th"); $ths.each(function(i){$(this).html((i+1)+(parseInt($(".pagesize").val())*(parseInt($(".pd>i").html())-1)));})} 
},

n=function(a){var b=a.config;b.page=b.totalPages-1;g(a)};this.appender=function(a,b){var c=a.config;c.rowsCopy=b;c.totalRows=b.length;c.totalPages=Math.ceil(c.totalRows/c.size);i(a,b)};this.defaults={size:parseInt($(".pagesize").val(),10),offset:0,page:0,totalRows:0,totalPages:0,container:null,cssNext:".next",cssPrev:".prev",cssFirst:".first",cssLast:".lastp",cssPageDisplay:".pd",cssPageSize:".pagesize", cssDisabled:"di",output:"Page <i>{page}</i> of {totalPages}",updateArrows:!1,positionFixed:false,
removeRows:true,
appender:this.appender};this.construct=function(a){return this.each(function(){var b=d.extend(this.config,d.tablesorterPager.defaults,a),c=this,e=b.container;d(this).trigger("appendCache");b.size=parseInt(d(".pagesize",e).val(),10);l(b);if(!b.removeRows)b.appender=null,k(c,b),d(this).bind("sortEnd.pager",function(){k(c,b);d(c).trigger("applyWidgets")});d(b.cssFirst,e).click(function(){c.config.page= 0;g(c);return!1});d(b.cssNext,e).click(function(){var a=c.config;a.page++;if(a.page>=a.totalPages-1)a.page=a.totalPages-1;g(c);return!1});d(b.cssPrev,e).click(function(){var a=c.config;a.page--;if(a.page<=0)a.page=0;g(c);return!1});d(b.cssLast,e).click(function(){n(c);return!1});d(b.cssPageSize,e).change(function(){var a=parseInt(d(this).val(),10),b=c.config;b.size=a;b.totalPages=Math.ceil(b.totalRows/b.size);b.pagerPositionSet=!1;g(c);m(c);return!1});d(this).bind("destroy.pager",function(){var a= c.config;a.size=a.totalRows;a.totalPages=1;i(c,a.rowsCopy);a.container.hide();a.appender=null;d(c).unbind("destroy.pager sortStart.pager")})})}}});d.fn.extend({tablesorterPager:d.tablesorterPager.construct})})(jQuery);

var options = {debug:true,headers:{0:{sorter:false},1:{sorter:'text'},4:{sorter:'peak'}},cssAsc:'hu',cssDesc:'hd',cssHeader:'he'};
$('form.pager').show();

if ($.browser.msie || $.browser.opera) 
{$('table').tablesorter(options)
.bind("sortEnd",function(){$ths = $("tbody th");$ths.each(function(i){$(this).html((i+1)+(parseInt($(".pagesize").val())*(parseInt($(".pd>i").html())-1)));});})
.tablesorterPager({container: $("form.pager")})}

/* For all other browsers, use my regular config */
else { $('table').tablesorter(options)
.bind("sortEnd",function(){$ths = $("tbody th");$ths.each(function(i){$(this).html(i+1);});})
.tablesorterPager({removeRows:false, container: $("form.pager")}) };

Pretty cool, huh? I'm actually using version 2.0.21 of the tablesorter (unmodified min) and the pager currently. I tried my changes on 2.3.2 of both, and for some reason, I got rebuild times of 900-1000ms in IE9. While barely within an acceptable range for me, it's still a LONG way off from my best times of 9-10ms I'm getting with 2.0.21. Not even my usual speed champ, Firefox, can beat that! (It gets ~20ms--definitely still blazing)

I'll test Versions 2.1 and 2.2, to see if I can find when IE9 starts slowing down. But aside from that, things are going much better now!

@Mottie
Owner

That's great to hear!

@camartinez1229

So, I think I'm gonna stick with the most recent 2.0.X version of Tablesorter I've found, 2.0.31, along with its corresponding pager (dated 2/16/12). Something changed between 2.0.X and 2.1.X, to cause IE9's rebuild times to slow to 700-1000ms, and I'm not quite sure what. I don't think it's worth my time anymore to try to figure it out, since I have now have everything working well enough: fast speeds in every current browser, and paging with correct row numbers. I even made my changes default to all browsers (instead of just IE and Opera), and that speeds things up for everyone. Firefox is my speed champ once again again with ~5ms rebuilds, haha, but Chrome ties it, and even occasionally edges ahead at ~2-3ms...simply phenomenal. Now, Opera is the one bringing up the rear, with ~250ms sorts and ~15ms rebuilds--still nothing to complain about, though.

Although I usually prefer using the latest version of scripts, I see no compelling reason for me to upgrade to 2.3.X, since it slows down IE somewhat. If this is something worth your looking to, then go for it. Otherwise, I am fine where I'm at, and you may close this issue. Thanks for your help, Mottie!

@Mottie
Owner

Ok, no worries. I do appreciate all of the troubleshooting that you've done! I'll find a better solution :)

@camartinez1229

You're welcome! I'll keep an eye out for any new updates, and, if I can help with any more troubleshooting, I'd be glad to.

@Mottie
Owner

Ok, I think I've improved sorting, rendering and even widget performance in IE9. I actually ended up removing the document fragments in some cases (in the widgets) as IE9 performed better without them and just hiding the tbody turned out to be better. I didn't change the appendToTable function much except to hide the tbody while appending, it seems to work better.

In my optimizations, I also found that parsing the data was extremely slow in IE9, so I opted for the fastest method of using textContent which was actually used in the original tablesorter, but I removed it assuming wasn't much different from using jQuery $(node).text() but I was wrong - see this jsPerf to see the differences in browsers... it's insane!

Now, I think one of the biggest issues in IE9 was the zebra widget. I noticed insanely slow times so I revert it back to the original code and oddly it was faster; but as a result, I added a new option named initWidgets which when set to false will NOT run any widget format code. The reason is that if you have an extremely large table that will use the pager plugin, all of the widgets will be applied before the pager plugin initializes. So setting this option to false will delay widget application until after the pager plugin has run.

I don't remember you using the filter widget, but just in case... I've also added a few filter widget options to delay searching which was also needed because of IE9 being so darn slow LOL.

@camartinez1229

I've finally gotten around to testing 2.3.5 and the updated pager, and running comparisons with my previous setup of 2.3.4 and the pager dated 2/16/12. IE9 did show some speed improvements in 2.3.5, such as 75-80ms initial cache build time for 738 rows, and overall init times of ~220ms. That included about 100ms time to apply my widget. I wouldn't have known of the widget time without the benchmark you put for timing them in 2.3.5, so, thanks for that! My only widget is repeated headers, visible every 25 rows. However, since by default, I have my table set to show exactly 25 rows per page, that means the repeated headers aren't visible unless the page size is increased. So, I wrapped my widget into an (if pagesize > 25) statement, and then wrappped that in a function bound to the pagesize selector. Now, my widget only loads when needed, and that shaves ~100ms off my init time, that I didn't even know was there, haha.

So, minus my widget now, init times averaged about 120ms in IE9 under 2.3.5. Pretty good. Initial cache build time was about 50ms higher under 2.3.4, meaning a nice ~30% improvement for me. However, rebuild times are still sluggish with the latest pager. The initial rebuild clocks in at over 1200ms, compared at ~350ms with 2.3.4 and the 2/16/12 pager. The times are about the same with 2.3.5 and the 2/16/12 pager, as well. Sorts/rebuilds are also fairly sluggish with the new pager, averaging about 950ms...a far cry from the 20-25ms I'd get with the older pager. I don't get it...I've tried comparing the differences between the 2/16/12 and 3/7/12 (I think that was the date? It was an early March that first exhibits the slower speeds in IE) pager, as well as the latest pager, and I can't pinpoint the slowdown. So, for now, I am sticking with the 2/16/12 pager.

Now, IE9 may not have seen great results with both the new sorter and pager, but IE8 actually saw more of an improvement. Weird, haha. Under 2.3.4 and the old pager, IE8 would get ~1400ms initial cache build times, and ~150ms initial rebuild times. Sorts/rebuilds would average 30ms or less. Now, with 2.3.5 and the new pager, initial cache build times were cut in half, to around 700ms--very good! But, the initial rebuild time slowed to ~500ms, and sorts/rebuilds would take ~550ms. Putting back the older pager brings those times back down, however, to ~250ms and 20-30ms, respectively.

So, with both IEs, 2.3.5 and the older pager gives me the best performance...that's what I'll be sticking with for now. However, 2.3.5 initially messed up my custom parser, only in IE8...yay, you just gotta love IE8 and its quirks, right? Haha, not! I traced the issue to getElementText, which changed in 2.3.5. As a test, I subbed in the function from 2.3.4, and that cleared up the issue (stuff not sorting properly), but at the expense of performance. In doing that, I lost the speed gains over 2.3.4. So, I played around with getElementText...

I determined that IE8 doesn't support the vastly superior textContent--no surprise there. That means it would fall back to the check for node.childNodes or node.innerHTML. Thinking the childNodes code was not working properly with my data, I removed that, leaving only the innerHTML option for IE8. Well, with that, I saw a further improvement to initial cache build times, down from ~700ms to ~450ms. However, it wrecked sorting on not only my custom parser column, but every other numeric column as well! Weird... Then I read up on innerText...it seemed like IE's version of textContent. I subbed that in, and it made all sorting work correctly. But, the init times went up to around 1200ms, and overall, everything felt slightly (though noticeably) slower. Seems like there's just no way to win with IE8, huh? Well, I did manage to win, finally :) I put back innerHTML, but this time added a regex replace method with it, to strip every b tag from my numbers, the culprit of IE8's wacky sorting. Surprisingly, it has a negligible affect on performance, as I still get init times of 450ms or less, initial rebuilds in ~220ms, and sorts/rebuilds in 20-30ms. I even substituted in the original text sorter, and that's helped speed things up even more. IE8 and IE9 would always take noticeably longer to sort my text columns than my number or date columns, but now they all take about the same time.

I've definitely had enough of IE8 for one day, or one week...actually, if I didn't have to put up with its quirks ever again, I'd be great! Haha.

@thezoggy
Collaborator

@mottie why not just remove the table from the DOM , do your logic then append it back?
look at #3 - http://jonraasch.com/blog/10-advanced-jquery-performance-tuning-tips-from-paul-irish

@Mottie
Owner

@thezoggy Well since I never know how the table is placed in the document, it's better not to remove it. For example, if I use the recommendation from that site and a table's parent is the body of the document. It gets removed, manipulated then appended back to the body... well now the table is at the bottom of the page. I guess I could wrap it and do all that stuff.

Anyway, I just switched to using document fragments because you can move all of the tbody contents into it, then append them back without removing the tbody itself... but as you can see, it's even slower in IE. The appendToTable is still using it and it seems the rebuild times are still slow.

I guess I'll try wrapping the table, removing, manipulating then appending it back just to see if IE is any happier. But let me finish working on this filter regex thing.

@thezoggy
Collaborator

additionally, here is another way people can speed up tables.. however there is a trade off:

table.tablesorter { table-layout: fixed }

Using the “automatic” layout algorithm (the table algorithm used by default in most browsers today), all of the table content is required in order to determine the final table layout. For larger quantities of tabular data, this can be MUCH slower than the “fixed” table layout algorithm, especially since more than one analysis might need to be performed on the table data. However, this algorithm does find sufficient minimum and maximum widths for each column, allowing all content in the table’s data cells to be appropriately rendered as specified by the author.

Under the “fixed” layout method, the entire table can be rendered once the first table row has been downloaded and analyzed. This can drastically speed up rendering time over the “automatic” layout method, but subsequent cell content may not fit in the column widths provided (the ‘clip’ and ‘overflow’ properties control the cell appearance in such a case.)

Thus if your table's column data length doesn't really vary from the 1st row onward.. then you could use this and save the browser a bit of work. Now if it does vary.. you'd have to deal with overflows/scrollbars/ugly things.. and no way would this be responsive (resize). Thus this feature is rarely used.. but still I figured I'd mention it since I came across it recently in my hunt for table optimizations.

@Mottie
Owner

Another update in v2.4. The tbody's are now detached then manipulated. There is a noticeable speed increase when sorting large tables.

@Mottie Mottie closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.