Indexeddb with datatables table.row.add.draw() slow render
Indexeddb with datatables table.row.add.draw() slow render
edys
Posts: 7Questions: 2Answers: 0
Hello i have indexeddb which draw into datatables. a new row add into the tables every 2-3 seconds. but the render performance is slow and show double multiplication from the real data in indexeddb. any advice would be helpful and appreciate. Thanks!
<script>
var table = $("#example1").DataTable({
"responsive": true,
"deferRender": true,
"orderClasses": false,
"bDeferRender": true,
"bProcessing": true,
"bSortClasses": false,
"oLanguage": {
"sSearch": "Pencarian",
"sLengthMenu": "Tampilkan _MENU_",
"sLoadingRecords": "Mohon tunggu - sedang mengambil data dari server...",
"sEmptyTable": "Belum ada data",
"sInfoEmpty": "Menampilkan 0 - 0 dari 0 data",
"sInfo": "Menampilkan _START_ - _END_ dari _TOTAL_ data",
"sInfoFiltered": "(Dicari dari _MAX_ total data)",
"sZeroRecords": "Data yang dicari tidak ada yang sesuai",
"oPaginate": {
"sNext": '<i class="fa fa-angle-right" ></i>',
"sPrevious": '<i class="fa fa-angle-left"" ></i>'
},
},
"order": [[ 0, "desc" ]],
"deferRender": true,
"orderClasses": false,
"bDeferRender": true,
"bProcessing": true,
"bSortClasses": false,
columnDefs: [{
targets: 1,
title: 'Berat',
render: function(data, type, full, meta) {
return data+' Kg';
},
},
{
targets: 0,
render: function(data, type, full, meta) {
return meta.row + 1;
},
},
{
targets: -1,
width:'40px',
render: function(data, type, full, meta) {
return '<button class="btn btn-danger btn-sm btn-icon" onclick="remove('+data+')"><i class="fa fa-times"></i></button>';
},
}
],
});
</script>
<script type = "text/javascript">
function readAll() {
nomor=1;
var bruto=0;
var objectStore = db.transaction("berat").objectStore("berat");
table.clear();
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
idtemp = cursor.value.id+1;
if(idtemp>idkeys){
idkeys=cursor.value.id+1;
}
//alert("Name for id " + cursor.key + " is " + cursor.value.berat + ", Tanggal: " + cursor.value.datetime);
//table.row.add( [cursor.key,cursor.value.berat,cursor.value.datetime,cursor.value.id] ).draw();
table.row.add( [cursor.key,cursor.value.berat,cursor.value.datetime,cursor.value.id] ).page('first').draw();
bruto = parseFloat(bruto) + parseFloat(cursor.value.berat);
cursor.continue();
nomor++;
}
document.getElementById('bruto').value=bruto.toFixed(2);
if(bruto.toFixed(2) == '0.00'){
table.clear().draw();
}
};
document.getElementById('overlay').style.display='none';
document.getElementById('addbutton_hide').style.display='none';
document.getElementById('addbutton_show').style.display='block';
}
function add() {
document.getElementById('addbutton_show').style.display='none';
document.getElementById('addbutton_hide').style.display='block';
setTimeout(function () {
fetch("http://localhost:8000/httplistener/")
.then(response => response.json())
.then(function(data1) {
//console.log(data1);
//document.getElementById('berat').value=data1.Berat;
var cekberat=data1.Berat;
if(cekberat>0){
document.getElementById('berat').value=data1.Berat;
var id=idkeys;
var bruto = document.getElementById('bruto').value;
var weight = document.getElementById('berat').value;
var currentdate = new Date();
var datetimes = currentdate.getFullYear() + "-"+ (currentdate.getMonth()+1) + "-" + currentdate.getDate() + " " + currentdate.getHours() + ":" + currentdate.getMinutes() + ":" + currentdate.getSeconds();
var request = db.transaction(["berat"], "readwrite").objectStore("berat").add({ berat: weight, datetime: datetimes });
request.onsuccess = function(event) {
document.getElementById('berat').focus();
bruto = parseFloat(bruto) + parseFloat(weight);
document.getElementById('bruto').value=bruto.toFixed(2);
//readAll();
document.getElementById('berat').value=data1.Berat;
//document.getElementById('berat').value='';
};
request.onerror = function(event) {
console.log("Unable to add data\r\Data is aready exist in your database! ");
document.getElementById('addbutton_hide').style.display='none';
document.getElementById('addbutton_show').style.display='block';
}
if(counter==sample){
keysample++;
var hitungsample = keysample;
document.getElementById('hitungsample').value=hitungsample;
playSound();
counter=0;
} else {
playBuzzer();
}
counter++;
nomor++;
keycounter++;
var hitungtimbang = keycounter;
document.getElementById('hitungtimbang').value=hitungtimbang;
readAll();
//cetak(nomor,weight);
//nomor++;
} else {
window.alert("Berat tidak boleh NOL (0) atau Tunggu Timbangan stabil.")
document.getElementById('addbutton_hide').style.display='none';
document.getElementById('addbutton_show').style.display='block';
}
})
.catch(function(error) {
// If there is any error you will catch them here
window.alert(" GAGAL TERHUBUNG KE INDIKATOR TIMBANGAN\r\ Ikuti langkah berikut :\r\r\ 1.) Sambungkan kabel timbangan ke Laptop\r\ 2.) Jalankan aplikasi pendukung\r\ 3.) Setelah aplikasi pendukung berjalan, berikan timbel ke timbangan\r\ 4.) Tunggu 10-20 detik lalu tekan CEK TIMBEL\r\ 5.) Pastikan berat pada jendela CEK TIMBEL sama dengan indikator timbangan")
document.getElementById('addbutton_hide').style.display='none';
document.getElementById('addbutton_show').style.display='block';
});
}, 500);
}
Edited by Colin - Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.
Answers
We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.
Cheers,
Colin
Thanks for response Sir.
I trried to paste my code to live datatables but not looks good. sorry i am new in datatables.
http://live.datatables.net/rifiviwe/1/
is there any approach just render last 10 record?
There is nothing obvious in the code that would suggest using
row.add()
to add one row every. 2-3 seconds would be slow. Looks like you start with an empty table then userow.add()
to populate the table. Does it start slow or become slow over time? Have you verified the problem is withrow.add()
and the time it takes to render the new row? Maybe try a timer like this to see how long it takes:What is showing double multiplication?
As Colin said we will need to see a running test case to help debug. We won't be able to debug performance nor calculations by looking at code snippets.
Datatables renders the rows being displayed. Looks like your table is set to show 10 rows on the page. when the new row is added Datatbles adds it to its data cache then, if sorting and paging dictates, it will render onto the page.
Kevin
Thanks Sir for response, i attach the google drive project URL below. It contains .zip and .sql file in order to offline debug when needed. I also write some explanation and user access in README.txt inside the drive.
https://drive.google.com/drive/folders/1T1jrEcL0o2zMJEUmdyG5VwQXKmmInSQY?usp=sharing
i will periodically check the discussion, thanks you.
It would be a great help to us, so we can help you, if you could host it somewhere and just give us a link to we can profile the performance.
Allan
Alright Sir, i hosted in the following url https://deployinsandbox.com/trial/uploadscale_old/public
Please open the README.txt in the drive (link https://drive.google.com/drive/folders/1T1jrEcL0o2zMJEUmdyG5VwQXKmmInSQY?usp=sharing ). There was login access user and password. Really thanks.
I'm not familiar with the indexeddb but each time the
Tambah Data
is clicked your code is fetching all the rows. For example the first time clicked one row of data is fetched. The second time two rows, the third three rows. After 50 clicks then 50 rows of data are fetched. You are clearing (table.clear()
) the Datatable each time and adding re-adding all the rows. Each of the 50 rows are added using this:This is calling
draw()
50 times which will increase the time it takes to populate the table. Thedraw()
API should only be called once after all the rows are added. You could remove it from therow.add()
call and call it once all the rows are added. Not sure where this would go in your solution.My suggestion is to fetch only the new row(s) each time the button is clicked. Don't clear the table and just add the newly fetched row. This is not a Datatables issue but in how you structure your code to fetch only the new data from indexeddb.
It looks like you have event handlers in the all() (
request.onsuccess
) and readAll() (objectStore.openCursor().onsuccess
) functions that are called when the DB accessed. These events are called once for each row added. Maybe there is a way with indexeddb to fetch all the rows at once to call the event handlers once and you can userows.add()
to add all.Use the indexeddb docs or maybe a site like Stack Overflow to learn how to use indexeddb in a more efficient manner.
Kevin
I forgot to mention that you might want to move the event handler creation in all() (request.onsuccess) and readAll() (objectStore.openCursor().onsuccess) outside the functions so they are only created once. This might help top fetch one row instead of all the previous rows too.
Kevin
thanks for reply Sir, few minutes ago i deployed the readAll() without table.clear() after adding and re-adding rows, based on the scenario where working with indexeddb using datatables not showing amount of data properly rendered compared to amount of data in indexeddb. But when by adding table.clear() before adding row gives better render datatables by showing proper amount of data compared to real stored datas. In the other side, there still same issue happened when datatables rendering process still running at the same time adding new row.. the chaos started. I will try to figure it out regarding suggestion moving the event handler outside functions. Thanks!