Why does datatable run so slow in IE,8,9 etc..
Why does datatable run so slow in IE,8,9 etc..
naijacoder
Posts: 6Questions: 0Answers: 0
Hi All I have a table of 400 rows and another of 100 rows.
But when i load it on IE 8 and above it runs quite slow.
But in firefox is much better.
Any ideas?
Is there a way to fix this.
Cheers
But when i load it on IE 8 and above it runs quite slow.
But in firefox is much better.
Any ideas?
Is there a way to fix this.
Cheers
This discussion has been closed.
Replies
The one thing I have found which really utterly kills IE performance is initialising the table in a hidden element (display:none). Doing that is a sure fire way to seriously hamper IE.
To improve speed, have a look at this FAQ: http://datatables.net/faqs#speed .
Allan
I've been pondering the same thing myself for a couple of days and I believe I have found a couple of useful optimizations in the _fnCreateTr method. Both optimizations are for poor insert times when adding JSON data with the fnAddData method (in Internet Explorer).
The first optimization is for the _fnRender function. I've modified the code so that it checks the _fnRender return type. If it returns a string, nothing changes, but if the return value is not a string, we assume it's a DOM object and use the dom method appendChild to add the cell content. Obviously this requires the user supplied fnRender definition to return a DOM object rather than a string.
In a simple test, inserting 100 rows with 26 columns (each column definition contains an fnRender function, I'm getting a performance improvement of approximately 30%. (was ~650ms now ~450ms)
The second optimization is for columns _not_ containing fnRender functions. All I do here is check if the value returned by _fnGetCellData looks like html [using a very naive approach]. If not, create a text node and append it to the cell. Otherwise falls back to the innerHTML method.
In a simple test, inserting 100 rows with 26 columns (no renderers), I'm getting a performance improvement of approximately 50% in IE9. (Was ~650ms now ~325ms).
[code]
if (typeof oCol.fnRender === 'function' &&
(!oCol.bUseRendered || oCol.mData === null))
{
var val = _fnRender( oSettings, iRow, i);
if (typeof val === 'string') {
nTd.innerHTML = val;
} else {
nTd.appendChild(val);
}
}
else
{
var val = _fnGetCellData( oSettings, iRow, i, 'display' );
if (val != null && val.toString().indexOf('<') == -1)
{
nTd.appendChild(document.createTextNode(val));
}
else
{
nTd.innerHTML = val;
}
}
[/code]
I think there may be a couple of other places where similar enhancements could be applied. Please let me know your thoughts.
Cheers,
Paul
Thanks for the suggestions.
> Obviously this requires the user supplied fnRender definition to return a DOM object rather than a string.
fnRender should always return a string - doing anything else is a new feature, and fnRender has now been deprecated and will be removed in v1.10, so I'd be reluctant to include that option for just 1.9.4. This method also doesn't take into account that in integer might be returned - it might be an idea to test for the 'nodeType' property of the returned object if you want to keep that method in a fork.
> All I do here is check if the value returned by _fnGetCellData looks like html [using a very naive approach].
This is an interesting idea as well. I think it would need to be expanded to include a test of entities, but that's an impressive speed boost. I'll certainly look into incorporating that one! Thanks.
Regards,
Allan
Thanks guys.I'm using Datatable to display data from Sql server directly using sharepoint designer.
But I woud try the approach using Ajax data and see if it gets faster using bDeferRender .
How does the datatable want the data via Ajax?.
Cheers
I had another go at this. I've managed to get a slightly better performance, without changing the return type of fnRender or checking whether the column text contains HTML just by using jQuery's $() to create the elements. I haven't tested all the combinations of options (hidden columns) etc. But the performance is improved for my simple test case (described in my previous comment) by at least 50% for both tests, i.e. with fnRender and without. I'm not sure what kind of magic jQuery is using to create the elements, but it seems to be a better approach despite the ugliness of the code :/
Cheers,
Paul
[code]
/**
* Create a new TR element (and it's TD children) for a row
* @param {object} oSettings dataTables settings object
* @param {int} iRow Row to consider
* @memberof DataTable#oApi
*/
function _fnCreateTr ( oSettings, iRow )
{
var oData = oSettings.aoData[iRow];
var nTd;
if ( oData.nTr === null )
{
var aRow = ['');
/* Process each column */
for ( var i=0, iLen=oSettings.aoColumns.length ; i
@reverselogic - Great to hear you got a speed boost. Thanks for sharing your code with us. One thing I would say is that fnRender is officially deprecated as of 1.9.4 (which will be released soon) and will be removed in 1.10, so I'd suggest using mRender in preference to fnRender.
Allan
Allan