fnScrollDraw slow in IE, possible fix inside

fnScrollDraw slow in IE, possible fix inside

BueyBuey Posts: 4Questions: 0Answers: 0
edited December 2012 in DataTables 1.9
Using DataTables 1.9.4:

One of our tables was taking between 3-7 seconds to load in IE, and through the profiler we traced it down to css.get([width or height]) calls happening within fnScrollDraw (taking about 70% of the draw time). I found that $(nSizer).width() was being called in multiple places and simply preassigned it to a variable, which dropped the time for this issue from 3-6 seconds to 200ms.

Is there a reason why $(nSizer).width() needs to be calculated separately for each child? Our table still looks the same, but I want to make sure.

Thanks.

Replies

  • BueyBuey Posts: 4Questions: 0Answers: 0
    Nevermind, this doesn't work, didn't notice it was a local variable for the function block.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Yup - the width get is frustratingly slow. There were some improvements that went into 1.9.4 to try and speed it up, and it did improve things by not invalidating the layout too often, but its still not super fast as the DOM with calculations are expensive, but necessary. I'm just not sure how it can be speed up further at the moment!

    Allan
  • BueyBuey Posts: 4Questions: 0Answers: 0
    I added some super hackish caching - caching the width, height, height(0), and outerWidth calls using either the element object as the key, or if the element has an "aria-label" attribute, using that label as the key instead (since the nSizer elements seem to be different javascript objects, but they all have the same size for the same aria-label). It does cut down the time significantly for my application (3.5s to 300ms), but I wouldn't recommend it as a general solution. Perhaps you can derive a solution from this.

    Using jshashtable: http://www.timdown.co.uk/jshashtable/

    [code]
    function _getCachedValue(sizer, func) {
    var key = sizer;
    if (func == 'width')
    key = sizer.attributes['aria-label'].value;

    var value = _sizerHash.get(key);

    if (!value) {
    var aValue;
    switch(func) {
    case 'width':
    aValue = $(sizer).width();
    break;
    case 'outerWidth':
    aValue = $(sizer).outerWidth();
    break;
    case 'height':
    aValue = $(sizer).height();
    break;
    case 'height(0)':
    aValue = $(sizer).height(0);
    break;
    }

    value = aValue;
    _sizerHash.put(key, value);
    }
    return value;
    }
    [/code]
  • BueyBuey Posts: 4Questions: 0Answers: 0
    Usage: replace $(nSizer).width() with _getCachedValue(nSizer, 'width')
This discussion has been closed.