0

html table has 4 levels of hierarchy in a tree type view. To give user a control to expand/collapse to any level, the following function is used. But this function takes more than 6 seconds to execute on IE8. It takes half of that time in Chrome. Any suggestions for how to speed this function up? Thanks

function showDetailLevel(level) {
    /*hide all the tr*/
    $('.dataRow').each(function() {
        $(this).hide();
    });
    /*collapse all the carets*/
    $('.detailsCarat').each(function() {
        if ($(this).hasClass('ui-icon-triangle-1-s')) {
            $(this).removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
        }                       
    }); 
    /*show the rows and expand all the carets that are at a tree level above the selected level*/
    for (var i=1; i<=level;i++) {   
        $('.detailLevel'+i).each(function() {
            $(this).show();
            if (i<level) {
                $(this).find('span.ui-icon-triangle-1-e').removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
            }
        }); 
    }   
}
user2760273
  • 123
  • 4
  • 11

2 Answers2

1

There are several performance hogs in the above script. The jQuery selectors with only CSS class-names and the unneeded toggling of many class-names jump out immediately.

Use a tag-name as well when selecting for class-names ($('tr.dataRow').each...).

The each statements are unnecessary, but probably not that much slower than the more concise script unless we consider using the tag names:

$('tr.dataRow').hide();

/*collapse all the carets*/
$('span.detailsCarat').toggleClass('ui-icon-triangle-collapsed');

More important, toggle just a single class-name wherever possible to avoid reflows (When does reflow happen in a DOM environment?). This is key. Your HTML should be nested in such a way that you can toggle a single CSS class in a container element and leverage CSS selectors to accomplish all that you need: hiding, showing, and changing appearances. For example, whatever style rules apply to 'ui-icon-triangle-1-s' should be in a rule with a selector such as div.container.active .ui-icon-triangle-1.

Community
  • 1
  • 1
cage rattler
  • 1,587
  • 10
  • 16
1

I'd try the following for starters: Add in the parent div to those classes as noted by #YOURCONTAINERDIV. I also added toggleClass for your add/remove class.

I am curious about this line of code: Can you explain why the loop of level, then doing an .each thru the collection of '.detailLevel' + i. I think alot of your issue is here.

for (var i=1; i<=level;i++) { 
    $('.detailLevel'+i).each(function() {
        $(this).show();

 function showDetailLevel(level) {
      /*hide all the tr*/
         $('#YOURCONTAINERDIV .dataRow').each(function() {
         $(this).hide();
});
/*collapse all the carets*/
$('#YOURCONTAINERDIV.detailsCarat').each(function() {
    if ($(this).hasClass('ui-icon-triangle-1-s')) {
        $(this).removeClass('ui-icon-triangle-1-s').toggleClass( ui-icon-triangle-1-e, ui-icon-triangle-1-s );                    
}); 
/*show the rows and expand all the carets that are at a tree level above the selected level*/
for (var i=1; i<=level;i++) {
    // I suspect a big issue is here as you are looping, then looping again thru
    // a collection of elements. 
    $('.detailLevel'+i).each(function() {
        $(this).show();
        if (i<level) {
            $(this).find('span.ui-icon-triangle-1-e').toggleClass( ui-icon-triangle-1-e, ui-icon-triangle-1-s );
        }
    }); 
}   

}

james emanon
  • 11,185
  • 11
  • 56
  • 97
  • thanks for the suggestion. That snippet that you think is a problem is used for when the user chooses to see level 3, then show the rows in level 1, level2, level3. Need to show all the rows in the levels that are lower than what the user chooses to see. – user2760273 Sep 17 '13 at 23:49
  • hmm, in jQuery you can select a range of elements to show, that "might" be quicker. I'll check back later and if you think that is a road you want to go down and haven't figured it out, I'll try to help further. – james emanon Sep 18 '13 at 01:12