DataTables and SocketIO Streaming
DataTables and SocketIO Streaming
Hello - Looking for some help or recommendation(s). I have an implementation where I use socketio to retrieve JSON results from a web service and want to stream these results to the datatable. Each result from the web service equates to one new row in the table. Almost like a real-time stock ticker. I have pasted my code below. It does work, this is not a question about getting it to work. My issue is performance. I've tried in IE, FF, Chrome and Safari. IE by far is the slowest and when even trying to stream 100 results to the DOM the web page completely hangs and becomes unresponsive. It looks like to me that the page is redrawing each time I add a new row of data to the table. The results come in so fast from the web service that the web page is playing catch up with each row I add. That is my theory.
With all that said maybe it is my execution with the code and how I am doing and not datatables itself. Actually I am almost certain. Can anyone take a look at the code below and provide a better suggestion? For every new row of data I get from the web service I call fnAddData. Maybe that's not the best way. I've tried with pagination on and off and the results are the same.
Thanks in advance.
[code]
<!DOCTYPE html>
var dataT;
var tempArray;
function streamResults(){
var aoColumns = [
{ "sTitle": "Title" }
];
$('#results').dataTable({
"bProcessing": true,
"aoColumns": aoColumns,
"bSort": false,
"bSortClasses": false,
"bDeferRender": true,
"iDisplayLength": 25,
"bLengthChange": false,
"bPaginate": true,
"oLanguage": { "sZeroRecords": "No Results Found" },
"bFilter": false,
"bDestroy": true
});
dataT = $('#results').dataTable();
var socket = io.connect("http://xxxx/getJSON");
socket.on("result", handle_result);
socket.emit("message", 100);
}
function handle_result(data) {
var be_response = JSON.parse(data);
processSearchResultsStream(be_response);
}
function processSearchResultsStream(data) {
if (data.body.object == undefined) {
return;
}
else {
var stuff= data['body']['stuff'];
tempArray = new Array(stuff);
dataT.fnAddData(tempArray);
}
}
[/code]
With all that said maybe it is my execution with the code and how I am doing and not datatables itself. Actually I am almost certain. Can anyone take a look at the code below and provide a better suggestion? For every new row of data I get from the web service I call fnAddData. Maybe that's not the best way. I've tried with pagination on and off and the results are the same.
Thanks in advance.
[code]
<!DOCTYPE html>
var dataT;
var tempArray;
function streamResults(){
var aoColumns = [
{ "sTitle": "Title" }
];
$('#results').dataTable({
"bProcessing": true,
"aoColumns": aoColumns,
"bSort": false,
"bSortClasses": false,
"bDeferRender": true,
"iDisplayLength": 25,
"bLengthChange": false,
"bPaginate": true,
"oLanguage": { "sZeroRecords": "No Results Found" },
"bFilter": false,
"bDestroy": true
});
dataT = $('#results').dataTable();
var socket = io.connect("http://xxxx/getJSON");
socket.on("result", handle_result);
socket.emit("message", 100);
}
function handle_result(data) {
var be_response = JSON.parse(data);
processSearchResultsStream(be_response);
}
function processSearchResultsStream(data) {
if (data.body.object == undefined) {
return;
}
else {
var stuff= data['body']['stuff'];
tempArray = new Array(stuff);
dataT.fnAddData(tempArray);
}
}
[/code]
This discussion has been closed.
Replies
Oof! You are destroying and recreating the table for every new row? Yup - that's going to kill performance!
Why not just add the new row using the API? Then you don't need to destroy and recreate the table every time!
*edit* I might have misunderstood your code - sorry. I think you can probably disregard what I've said above...
How fast are the results coming in? If you are doing fnAddData very quickly you would be better off putting a debounce in, so it will do a single draw, every 1 second (for example).
Allan
[code]
$('#results').dataTable({
"bProcessing": true,
//"aaData": _gridResults,
"aoColumns": aoColumns,
//"aaSorting": [[2, "asc"]],
"bSort": false,
"bSortClasses": false,
"bDeferRender": true,
"iDisplayLength": 25,
"bLengthChange": false,
"bPaginate": true, //keep pagination on; if we disable it, it will display all results at once and we don't want this!
"oLanguage": { "sZeroRecords": "No Results Found" },
"bFilter": false,
//"bDestroy": true
});
[/code]
[code]
function processSearchResultsStream(data) {
if (data.body.object == undefined) {
return;
}
else {
var stuff= data['body']['stuff'];
tempArray = new Array(stuff);
dataT.fnAddData(tempArray);
}
}
[/code]
debounce, are you referring to the jQuery throttle mechanism $.debounce? My quick web search finds this: http://benalman.com/projects/jquery-throttle-debounce-plugin/
*OK, not jQuery. Looks like a custom library that this gentleman put together.
A little, but not much.
Debounce - sorry, yes, it should have said throttle, they are slightly different. Basically you want a little timer that is started when you do your fnAddData (with the second parameter as `false` to prevent the draw) and is reset when there is a new fnAddData call made. After a timeout it will trigger the fnDraw call.
Allan