jumpdart
jumpdart

Reputation: 1722

.height(item.height()) jquery too slow in IE! Alternatives?

I am trying to set the height of absolutely positioned items to match the height of their container element. The problem is that there are hundreds of these elements. The standard code in the title runs great in chrome, but drags like crazy in IE. How should i mitigate this issue?

    //Too SLOW in IE
    var starttime = new Date().getTime();
    $("#grdSchedule > tbody > tr").each(function(i) {
        thisRow = $(this);
        thisRow.children(".stickyCol").height(thisRow.height());
        //thisRow.children().slice(0, 1).css('height', thisRow.css('height'));            
    });
        var taskTime = (new Date().getTime() - starttime) / 1000;
        alert("cell height stretch: " + taskTime); 

It seems as if just setting the height doesnt sloe it doen that much, but setting the height from a .height() of something else really causes IE to choke.

I have tries .css() instead with a little boost but not much.

Here is a fiddle to fiddle with: Fiddle AWAY!!!

Upvotes: 4

Views: 2058

Answers (4)

jumpdart
jumpdart

Reputation: 1722

Looks like the precalcs on their own is enough to really speed things up, and comes with the benefit of not worrying about any complications from detaching

    var starttime = new Date().getTime();
    var stickyCols = 1;
    //get row heights
    var rowHeights = new Array();
    $("#grdSchedule > tbody > tr").each(function(i) {
        rowHeights[i] = $(this).css('height');
    });

    //Now SUPERDUPERFAST in IE
    //var $table = $("#grdSchedule").detach();            
    $("#grdSchedule > tbody > tr").each(function(i) {
    //$(" > tbody > tr", $table).each(function(i) {
        thisRow = $(this);
        thisRow.children("td").slice(0, stickyCols).css('height', rowHeights[i]);              
    });
    //$("#scrollDiv_top").append($table);
    var taskTime = (new Date().getTime() - starttime) / 1000;
    alert("cell height stretch: " + taskTime); 

FIDDLE

Upvotes: 0

Elliot B.
Elliot B.

Reputation: 17661

With IE9, I went from 1.6 seconds to 0.031 seconds. With Chrome, I went from 0.302 seconds to 0.018 seconds.

Working example with detach() (fastest, but will cause layout problems if you delayed the re-insertion of the table--that is, if you allow the page to re-render without the table in the DOM).

Working example with a plain DocumentFragment clone

The key is to clone the table as a DocumentFragment (or temporarily remove it from the DOM with detach() and manipulate the cell heights of the cloned table (i.e., before the table is part of the DOM). Then after all the height calculations have been made, replace the original table with the cloned table.

The .height() calculations weren't slowing you down, it's the fact you were traversing and manipulating the DOM in a big loop. Of the big three browsers, Internet Explorer is the slowest at DOM manipulation.

For some further reading, a while back I put together some DOM insertion benchmarks that give a good measure of relative browser performance with the DOM. John Resig has also written on the use the DocumentFragments and DOM manipulation: http://ejohn.org/blog/dom-documentfragments/

Upvotes: 3

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324650

What's wrong with just setting height:100% on the absolutely-positioned element?

Updated Fiddle

Upvotes: 0

Joseph Silber
Joseph Silber

Reputation: 219936

Avoid creating a separate object for the row, and cache the row's height:

 $('#grdSchedule > tbody > tr').each(function () {
    var height = $.css(this, height);
    $('.stickyCol', this).css('height', height );           
});

Upvotes: 0

Related Questions