Data table hangs browser when Large data in the table
Data table hangs browser when Large data in the table
amit_routadigital
Posts: 2Questions: 1Answers: 0
Data table hangs browser when Large data in the table
Datatable search pane with large data set hangs for few second .
My project using react(fe) + node.js(be)
scenarioTable = new DataTable(tableRef?.current, {
fixedColumns: {
leftColumns: 2,
left: 1,
start: 2,
},
fixedHeader: true,
scrollX: 300,
scrollY: ((windowDimensions?.height/1.5)-100),
scrollCollapse: true,
scrollInfinite: true,
colReorder: colReorder_options,
data: scenarioData,
language: {
loadingRecords: " ",
processing: "Loading...",
},
buttons: html5Buttons(),
destroy: true,
pageLength: 100,
lengthMenu: [
[10, 25, 50, 100, 500, -1],
["10", "25", "50", "100", "500", "Show all"],
],
aaSorting: [],
searchPanes: {
layout: 'columns-4',
orderable: false,
threshold: 1,
},
dom: "PBfrtip",
columns: scenarioColumnsHeaders?.map((element, index) => {
// console.log(element, "=====element")
element.render = function (data, type, row) {
if (
type === "display" &&
data != null &&
typeof data === "string"
) {
data = data.replace(/<(?:.|\\n)*?>/gm, "");
data = data.replaceAll('"', "");
const dataTitle = data;
data = data.split(",").join(",<br/>")
if (data.length > 100 && data[element.data] == 'Business Capability') {
return `<span class='show-ellipsis text-wrapped' data-title='${dataTitle}'>${data.substr(
0,
100
)} ...</span><span class='no-show'>${data.substr(100)}</span>`;
} else if (data.length > 50) {
return `<span class='show-ellipsis text-wrapped' data-title='${dataTitle}'>${data.substr(
0,
50
)} ...</span><span class='no-show'>${data.substr(50)}</span>`;
} else {
return data || "";
}
} else {
return data || "";
}
}
return element;
}),
select: {
style: "multi",
selector: "td:first-child",
},
initComplete: function (settings, json) {
var api = this.api();
replacePlaceholder();
// this.api().searchPanes.rebuildPane();
$('#int-app-table').on('dblclick', 'tbody td', async function (e) {
let container = $("div.comment-content");
container.remove();
message.destroy()
if (UserService.hasRole(['Admin', 'Editor'])) {
setDefaultSelectValue([]);
setModalSelectOpen(false);
setModalTextareaOpen(false);
setInputValue('');
let columnIndex = $(this).index();
var rowIndex = $(this).closest('tr').index();
let row = scenarioTable.row(this).data();
let scenarioId;
if (row && row?.DT_RowId) {
scenarioId = row.DT_RowId.split("_")[2];
}
let columnId = null;
let availableColumnId = null;
const column = scenarioColumns[columnIndex - 1];
if (scenarioColumnsResponse?.length != 0) {
for (let item of scenarioColumnsResponse) {
if (item?.columnName == column?.label) {
columnId = item.id;
availableColumnId = item.availableColumnId;
break
}
}
}
let value = $(this).text();
if ($(this).find('span.text-wrapped').length !== 0) {
value = $(this).find('span.text-wrapped').attr('data-title');
}
let obj = {
scenarioId: scenarioId,
rowIndex: rowIndex,
columnId: columnId,
availableColumnId: availableColumnId,
column: column,
row: row,
}
setSelectSubmitData(obj)
if (column?.type == "select") {
const dropdownVal = await ScenarioServices.getScenarioDropdownValue({
"columnId": availableColumnId,
})
if (dropdownVal.data) {
setOptions(dropdownVal.data)
} else {
setOptions(column?.ipOpts)
}
let trimmedValues;
if (value.includes(',')) {
trimmedValues = value.split(',').map(item => item.trim());
setDefaultSelectValue(trimmedValues)
} else {
trimmedValues = [value];
setDefaultSelectValue(trimmedValues)
}
setModalSelectOpen(true)
} else {
setTextareaValue(value);
setModalTextareaOpen(true)
}
} else {
message.error("You are not authorised to update the data!")
}
})
$('#int-app-table').on('contextmenu', 'tbody td', function (event) {
message.destroy()
if (UserService.hasRole(['Admin', 'Editor'])) {
setSelectSubmitData({})
var columnIndex = $(this).index();
let row = scenarioTable.row(this).data()
if (row) {
let scenarioId = row.DT_RowId.split("_")[2];
let rowId = row.DT_RowId.split("_")[1];
let columnId = null;
let availableColumnId = null;
const column = scenarioColumns[columnIndex - 1];
if (scenarioColumnsResponse?.length != 0) {
for (let item of scenarioColumnsResponse) {
if (item?.columnName == column?.label) {
columnId = item.id;
availableColumnId = item.availableColumnId;
break
}
}
}
setSelectSubmitData({
rowId: rowId, columnId: availableColumnId, scenarioId: scenarioId
})
show({
event,
props: {
key: 'value'
}
})
}
} else {
message.error("You are not authorised to apply comment!")
}
})
$('.dataTables_scrollHead').css({
'overflow-x': 'scroll'
}).on('scroll', function (e) {
var scrollBody = $(this).parent().find('.dataTables_scrollBody').get(0);
scrollBody.scrollLeft = this.scrollLeft;
$(scrollBody).trigger('scroll');
});
},
createdRow: function (row, data, dataIndex) {
if (data['column_base']) {
$(row).css('background-color', '#d8e5f1');
$(row).css('font-weight', '600');
}
for (let key in data) {
if (key.includes('_comment') && data[key] && data[key].length > 0) {
const columnIndex = getColumnIndexByKey(scenarioColumnsHeaders, key.replace('_comment', ''));
if (columnIndex !== -1) {
const cell = $(row).find('td:eq(' + columnIndex + ')');
cell.addClass('comment-added');
const commentData = data[key];
const commentContent = commentData.map(item => {
const formattedDate = new Date(item.createdAt).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
return `
<strong>User:</strong> ${item.userEmail ? item.userEmail : '-'}<br>
<strong>Comment:</strong> ${item.comment}<br>
<strong>Date:</strong> ${formattedDate}<br>
<hr>
`;
}).join('');
// Add Bootstrap popover
cell.attr('data-toggle', 'popover');
cell.attr('data-html', 'true'); // Enable HTML content
cell.attr('data-content', commentContent);
// cell.attr('data-trigger', 'hover');
cell.attr('data-placement', "bottom");
// cell.popover();
}
}
if (key.includes('_difference') && data[key]) {
const columnIndex = getColumnIndexByKey(scenarioColumnsHeaders, key.replace('_difference', ''));
if (columnIndex !== -1) {
const cell = $(row).find('td:eq(' + columnIndex + ')');
cell.css('color', '#ea0505');
cell.css('font-style', 'italic')
}
}
}
},
searchDelay: 350,
drawCallback: function (settings) {
let searchText = $('#int-app-table_filter input[type=search]').val();
if (settings?.iDraw >= 2) {
setHighlight(searchText);
}
$('.paginate_button.next:not(.disabled)', this.api().table().container())
.on('click', function () {
alert('next');
})
}
});
Edited by Colin - Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.
Answers
When you say "large data", how large are we talking? For DOM source data, which your config suggests you're using, the recommendation is up to 5k rows.
This section of the FAQ should help, it discusses various techniques to improve performance.
Colin
Thanks for quick reply @colin .
But still it is not working properly as i used these following options.Please guide me if i am doing something worng.
``` table's html
```
with page length 25 it is working fine but with page length 100 browser hangs.
From Colin:
Do you get errors in the browser's console?
What exactly happens, ie, can you click elements outside of Datatables?
Does it hang on initial loading or when interacting with the Datatable?
Can you post a link to your page or test case replicating the issue so we can help debug?
https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case
Kevin