Table slow in FF, fast in Chrome
Table slow in FF, fast in Chrome
koosvdkolk
Posts: 169Questions: 0Answers: 0
I create a table using:
[code]
$tableElement.dataTable( {
"sScrollY": plugin.settings.tableHeight+"px",
"sScrollX": "100%",
"aaData": tableData,
"bStateSave": true,
"bSortClasses": false,
"bDeferRender": true,
"bAutoWidth": false,
"sPaginationType": "full_numbers",
"sDom": 'z<"H"<"#datatable_'+plugin.settings.id+'_menu"f>r>tSpi',//typeArray,
"aoColumns": getColumnConfigArray(),
"bLengthChange": false,
"fnRowCallback": function( nRow, aData ) {
/* add primary key value to row, so we can easily get it when the row is selected */
jQuery(nRow).data('dataGrid.primaryKeyValue', aData[plugin.globals.primaryKeyIndex]);
return nRow;
},
"fnStateLoadCallback": function ( oSettings, oData ) {
/* get state of column search inputs, used to set the values */
columnSearchInputState = oData.aaSearchCols;
return true;
},
"fnDrawCallback": function( oSettings ) {
_onTableRedraw(oSettings);
console.log('_onTableRedraw');
},
"fnInitComplete": function() {
/**
* Keep reference to the datatable object
**/
plugin.dataTableObject = $tableElement.dataTable();
/*new FixedColumns( plugin.dataTableObject );*/
/**
* Call _onWindowResize, because it will set the wrapper with
**/
_onWindowResize();
/**
* Show item after init, see fireGridAndFormJS.php
**/
if(typeof(tableid) != "undefined") {
this.fnFilter( tableid, 0 );
selectRowById(plugin.settings.id);
//this.oScroller.fnScrollToRow(0);
}
/**
* Filters rows, as stored in in cookie
**/
var oSettings = $tableElement.dataTable().fnSettings();
for ( var i=0 ; i0)
{
$tableElement.children("tfoot").find("input").eq(i).val(oSettings.aoPreSearchCols[i].sSearch);
}
}
/**
* Filter columns, as stored in cookie
**/
for ( var i=0 ; i
[code]
$tableElement.dataTable( {
"sScrollY": plugin.settings.tableHeight+"px",
"sScrollX": "100%",
"aaData": tableData,
"bStateSave": true,
"bSortClasses": false,
"bDeferRender": true,
"bAutoWidth": false,
"sPaginationType": "full_numbers",
"sDom": 'z<"H"<"#datatable_'+plugin.settings.id+'_menu"f>r>tSpi',//typeArray,
"aoColumns": getColumnConfigArray(),
"bLengthChange": false,
"fnRowCallback": function( nRow, aData ) {
/* add primary key value to row, so we can easily get it when the row is selected */
jQuery(nRow).data('dataGrid.primaryKeyValue', aData[plugin.globals.primaryKeyIndex]);
return nRow;
},
"fnStateLoadCallback": function ( oSettings, oData ) {
/* get state of column search inputs, used to set the values */
columnSearchInputState = oData.aaSearchCols;
return true;
},
"fnDrawCallback": function( oSettings ) {
_onTableRedraw(oSettings);
console.log('_onTableRedraw');
},
"fnInitComplete": function() {
/**
* Keep reference to the datatable object
**/
plugin.dataTableObject = $tableElement.dataTable();
/*new FixedColumns( plugin.dataTableObject );*/
/**
* Call _onWindowResize, because it will set the wrapper with
**/
_onWindowResize();
/**
* Show item after init, see fireGridAndFormJS.php
**/
if(typeof(tableid) != "undefined") {
this.fnFilter( tableid, 0 );
selectRowById(plugin.settings.id);
//this.oScroller.fnScrollToRow(0);
}
/**
* Filters rows, as stored in in cookie
**/
var oSettings = $tableElement.dataTable().fnSettings();
for ( var i=0 ; i0)
{
$tableElement.children("tfoot").find("input").eq(i).val(oSettings.aoPreSearchCols[i].sSearch);
}
}
/**
* Filter columns, as stored in cookie
**/
for ( var i=0 ; i
This discussion has been closed.
Replies
You could always show a message suggesting the user upgrade to Chrome ;-)
(I jest...)
Allan
Slow is that it takes +/- 5-10 seconds for every table redraw event. So when search, each letter typed will create a non-responsive FF for 5-10.
On http://pkedu.wmmrc.nl/firebug_slow_ff.png you will find the screenshot of the Firebug profile when a table redraw event is triggered. Its in Dutch, but the words are not to difficult to translate:
Functie = function
Aanroepen = calls
Procent = Percent
Eigen tijd = own time
Tijd = time
Gem = Avg
Bestand = File
What amazes me is the fact that one table redraw causes 254.627 function calls!
I hope this give you a clue. Making a public demo is quite difficult right now, but if needed, I can provide you with that.
Thanks,
Allan
It looks like the problem is really in the search function, which is called a lot of times...
What calls are you using to redraw the table? Is it server-side processing, client-side Ajax, deferred rendering etc?
Allan
[code]
function _fnGetCellData( oSettings, iRow, iCol, sSpecific )
{
console.log(iredrawcount++);
console.trace();
...
}
[/code]
When I add 1 letter to the search input field, this function is called 2 times for each cell.
So: with 37 columns:
and 1 row: 2x37x1 = 74 calls
and 2 rows 2x37x2 = 148 calls
etc.
To me this seems... not very scalable. There are two types of traces:
Trace 1:
[code]
_fnGetCellData(oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, iRow=0, iCol=3, sSpecific="filter")jquery...bles.js (line 734)
_fnGetRowData(oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, iRow=0, sSpecific="filter")jquery...bles.js (line 716)
_fnBuildSearchArray (oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, iMaster=1)jquery...bles.js (line 2216)
_fnFilter(oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, sInput="a", iForce=0, bRegex=false, bSmart=true, bCaseInsensitive=true)jquery...bles.js (line 2162)
_fnFilterComplete (oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, oInput=Object { sSearch="a", bRegex=false, bSmart=true, meer...}, iForce=undefined)jquery...bles.js (line 2021)
(?)(e=Object { originalEvent=Event keyup, type="keyup", timeStamp=1330346617428, meer...})jquery...bles.js (line 1978)
handle(a=Object { originalEvent=Event keyup, type="keyup", timeStamp=1330346617428, meer...})jquery....min.js (line 63)
add()jquery....min.js (line 57)
[/code]
Trace 2:
[code]
_fnGetCellData(oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, iRow=1, iCol=0, sSpecific="filter")jquery...bles.js (line 734)
_fnGetRowData(oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, iRow=1, sSpecific="filter")jquery...bles.js (line 716)
_fnBuildSearchArray (oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, iMaster=0)jquery...bles.js (line 2216)
_fnFilterComplete (oSettings=Object { oFeatures={...}, oScroll={...}, oLanguage={...}, meer...}, oInput=Object { sSearch="a", bRegex=false, bSmart=true, meer...}, iForce=undefined)jquery...bles.js (line 2049)
(?)(e=Object { originalEvent=Event keyup, type="keyup", timeStamp=1330345762917, meer...})jquery...bles.js (line 1978)
handle(a=Object { originalEvent=Event keyup, type="keyup", timeStamp=1330345762917, meer...})jquery....min.js (line 63)
add()jquery....min.js (line 57)
[/code]
What happens is (I put it in pseudo code):
[code]
for (iRow=numberOfRows-1; iRow>=0; iRow--) {
for (iCol = 0 ; iCol < numberOfCols ; iCol++ ) {
_fnGetCellData called according to Trace 1
}
}
fnDrawCallback called
for (iRow=numberOfRows-1; iRow>=0; iRow--) {
for (iCol = 0 ; iCol < numberOfCols ; iCol++ ) {
_fnGetCellData called according to Trace 2
}
}
[/code]
So, as I mentioned, perhaps you can give me some details about how you are actually using DataTables so I can see where it might be possible to improve things.
As an example of how draw times should be: http://datatables.net/release-datatables/extras/Scroller/large_js_source.html . It takes a little while to load the page, a large part of which is due to the array creation, however if you click a column header, you should see how fast a sort and redraw occurs.
Allan
Thanks, I will try to fabricate an online sample.
About http://datatables.net/release-datatables/extras/Scroller/large_js_source.html: did you also try to have more columns than rows? E.g. 30 columns and 1500 rows? This should not make a difference, but you never know :)
Koos
1
12
123
1234
12345
If there would be a timeout of e.g. 200 ms before search starts (and reset by each keyup), it would only search one, for 12345
This is the weirdest thing I have seen for years. I wanted to make a test for you:
1) I saved my webpage in FF containing the DataTable using 'File' -> 'Save page as' to test.html
2) In test.html, I replaced the innerHTML of the with the original HTML of my webpage (as the method in point 1 will save the [i]rendered[/i] HTML, not the original HTML).
Guess what?
test.html is almost as fast as Google Chrome!
I have absolutely no clue of how this is possible.
Use this plug-in: http://datatables.net/plug-ins/api#fnSetFilteringDelay
> I have absolutely no clue of how this is possible.
Lol - very odd! I'm afraid I don't have any suggestions on what might be happening there :-(. It sounds like it should be exactly the same. Might you have cache disabled in Firefox or something?
Allan
This is when trying to display a dataTable with approximately 60 rows and 41 columns (with a lot of fnRender calls). Chrome's developer tools don't seem to be slowed down at all.
Thanks for noting this!
Allan
Would it be an idea to have this somewhere on the website (if not already the case?). Do not use FireBug with large tables?
Most other widgets like this include the type ahead delay (via setTimeout and cancelling pending requests within a msec range) as a default. Is there a reason datatables.net doesn't? I can't see a reason you wouldn't want this, as it would give a much better user experience by default.
FYI this isn't related to big tables... we noticed this issue when testing on a table with 1 row in it.
@rpocklin:
> Is there a reason datatables.net doesn't?
Yes, typically most tables that are used with DataTables are client-side and typically < 500 rows (at least in my experience (the new debugger might be able to confirm that as time goes by and information is gathered). With such tables, the client-side processing of key press filtering is extremely responsive, providing, in this case, a much better user experience. Of course this doesn't hold true in all cases, and that's what the plug-ins are for :-) (for example where server-side processing is enabled - are you using SSP?).
The plug-ins can and should be used where appropriate, but this isn't turn in all of cases and therefore adding it to the DataTables core would be a bad thing - that's how library bloat occurs and I'm going to harsh on accepting code (from myself in particular!) into the core that adds extra weight to it. I'd much rather keep DataTables to a sensible size (currently 68K) than just adding the odd feature here and there and ending up with a 1/4MB Javascript file!
Allan