Sou*_*jee 3 html javascript jquery html-table dynamic
这就是我在通过 ajax 调用从数据库获取数据后创建表并渲染到 aspx 页面的方式。我检查了存储过程执行时间,只有 1.5 秒,页面中的表大约在 7-8 秒内呈现。我需要优化速度。有什么建议我该怎么做吗?
$.ajax({
method: 'POST',
//async: false,
data: json_data,
dataType: 'json',
url: json_url
}).success(function (response) {
if (response.IsError) {
showError('Did not receive values from XRM.');
} else {
var webResponse = response;
var dataSet = webResponse["Orders"];
var statuses = [];
//console.log(dataSet);
if (table_role == 'pending') {
statuses = [
{
'id': 39,
'name': 'Pending Scheduling',
'class': 'schedule',
'color': '#7C44BC',
'order': 0
},
{
'id': 40,
'name': 'Pending Screening',
'class': 'screening',
'color': '#8e8e00',
'order': 1
},
{
'id': 41,
'name': 'Pending Pre-Auth',
'class': 'preauth',
'color': '#cc8500',
'order': 2
},
{
'id': 42,
'name': 'Ready For Confirmation',
'class': 'confirm',
'color': '#cc0070',
'order': 3
},
{
'id': 1,
'name': 'Open',
'class': 'open',
'color': null,
'order': 4
},
{
'id': 2,
'name': 'New Order',
'class': 'neworder',
'color': null,
'order': 5
},
{
'id': 3,
'name': 'Changed',
'class': 'changed',
'color': '#cd4e3e',
'order': 6
},
{
'id': 5,
'name': 'Approved',
'class': 'approved',
'color': '#6aa745',
'order': 7
},
{
'id': 6,
'name': 'On Hold',
'class': 'onhold',
'color': '#009acd',
'order': 8
},
{
'id': 11,
'name': 'In Queue',
'class': 'queue',
'color': null,
'order': 9
}
];
// For customers, change labels
if (is_customer) {
statuses[5]['name'] = 'Submitted to SMS';
statuses[9]['name'] = 'Approved';
}
} else if (table_role == 'preauth') {
statuses = [
{
'id': 29,
'name': 'More Info Needed',
'class': 'moreinfo',
'order': 0
},
{
'id': 43,
'name': 'Phone Order',
'class': 'phone',
'order': 1
},
{
'id': 30,
'name': 'Received Order',
'class': 'received',
'order': 2
},
{
'id': 31,
'name': 'Waiting on Documentation',
'class': 'waiting',
'order': 3
},
{
'id': 32,
'name': 'Courtesy Call Pending',
'class': 'courtesy-pending',
'order': 4
},
{
'id': 33,
'name': 'Courtesy Call Complete',
'class': 'courtesy-complete',
'order': 5
},
{
'id': 34,
'name': 'In Pre-Authorization',
'class': 'preauth',
'order': 6
},
{
'id': 35,
'name': 'Additional Docs Needed',
'class': 'addtldocs',
'order': 7
},
{
'id': 36,
'name': 'Pending Authorization',
'class': 'pending',
'order': 8
}
];
}
// Remove any "sorting" backgrounds from headers
$th.removeClass('otable__sort');
// If no orders available
if ($.isEmptyObject(dataSet)) {
$table.find('.otable__empty').css('display', 'table-cell');
} else {
// Loop through orders
$.each(dataSet, function (key, value) {
if (table_role == 'pending') {
var id = (value['ID'] == null) ? '' : value['ID'],
date = (value['ID'] == null) ? '' : value['ExamDate'],
billing = (value['BillCode'] == null) ? '' : value['BillCode'],
scanner = (value['ScannerCode'] == null) ? '' : value['ScannerCode'],
units = (value['Unit'] == null) ? '' : value['Unit'],
by = (value['EmployeeName'] == null) ? '' : value['EmployeeName'],
status = value['StatusID'],
customer = value['Customer'],
location = '';
// Build location string
if (value['Facility']) {
location += value['Facility'] + '<br>';
}
if (value['City'] && value['State']) {
location += value['City'] + ', ' + value['State'];
}
} else if (table_role == 'preauth') {
var id = (value['ID'] == null) ? '' : value['ID'],
poid = (value['POID'] == null) ? '' : value['POID'],
site = (value['Site'] == null) ? '' : value['Site'],
patient = (value['PatientName'] == null) ? '' : value['PatientName'],
insurance_co = (value['InsuranceCo'] == null) ? '' : value['InsuranceCo'],
received_date = (value['ReceivedDate'] == null) ? '' : value['ReceivedDate'],
exam_date = (value['ExamDate'] == null) ? '' : value['ExamDate'],
updated_date = (value['UpdatedDate'] == null) ? '' : value['UpdatedDate'],
status = value['StatusID'],
priority = (value['Priority'] == null) ? 0 : value['Priority'],
custid = (value['custID'] == null) ? '' : value['custID'];
}
// Find status from ID
var object = $.grep(statuses, function (element, index) {
return element['id'] == status;
});
object = object[0];
// Get status name
var status_name = object['name'],
status_pos = object['order'],
status_class = object['class'],
datestring = '',
received_datestring = '',
exam_datestring = '',
updated_datestring = '';
// Build date strings
if (date) {
datestring = splitDate(date);
}
if (received_date) {
received_datestring = splitDate(received_date);
}
if (exam_date) {
exam_datestring = splitDate(exam_date);
}
if (updated_date) {
updated_datestring = splitDate(updated_date);
}
// Build Time strings
if (updated_date) {
updated_timestring = splitTime(updated_date);
}
else {
updated_timestring = '';
}
// Convert priority for sorting
var priority_order;
if (priority) {
if (priority == 0) {
priority_order = 2;
} else if (priority == 5) {
priority_order = 1;
} else if (priority == 10) {
priority_order = 0;
}
}
// HTML for table row
var $row;
if (table_role == 'pending') {
if (!is_customer && (is_scheduler || is_retail)) {
$row = $('<tr class="otable__row otable__row--' + status_class + '">' +
'<td class="otable__id"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + id + '</a></td>' +
'<td class="otable__date" data-sort-value="' + date + '"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + datestring + '</a></td>' +
'<td class="otable__billing"><a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')>' + billing + '</a></td>' +
'<td class="otable__scanner"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + scanner + '</a></td>' +
'<td class="otable__loc"><a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')>' + location + '</a></td>' +
'<td class="otable__units"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + units + '</a></td>' +
'<td class="otable__by"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + by + '</a></td>' +
'<td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + date + '"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + status_name + '</a></td>' +
'</tr>');
} else if (!is_customer && (!is_scheduler || !is_retail)) {
$row = $('<tr class="otable__row otable__row--">' +
'<td class="otable__id"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + id + '</a></td>' +
'<td class="otable__date" data-sort-value="' + date + '"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + datestring + '</a></td>' +
'<td class="otable__billing"><a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')>' + billing + '</a></td>' +
'<td class="otable__scanner"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + scanner + '</a></td>' +
'<td class="otable__loc"><a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')>' + location + '</a></td>' +
'<td class="otable__units"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + units + '</a></td>' +
'<td class="otable__by"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + by + '</a></td>' +
'<td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + date + '"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + status_name + '</a></td>' +
'</tr>');
} else {
$row = $('<tr class="otable__row otable__row--customer otable__row--' + status_class + '">' +
'<td class="otable__id"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + id + '</a></td>' +
'<td class="otable__date" data-sort-value="' + date + '"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + datestring + '</a></td>' +
'<td class="otable__units"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + units + '</a></td>' +
'<td class="otable__by"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + by + '</a></td>' +
'<td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + date + '"><a href=/Customer/FDGOrders.aspx?oid=' + id + '>' + status_name + '</a></td>' +
'</tr>');
}
} else if (table_role == 'preauth') {
var insurance_sort_val = priority_order;
if (exam_date && exam_date.indexOf('0001-01-01') < 0) {
insurance_sort_val = priority_order + ' ' + exam_date;
} else if (received_date) {
// Force items with null exam date to bottom, then sort by received date
insurance_sort_val = priority_order + ' Z ' + received_date;
}
$row = $('<tr class="otable__row otable__row--' + status_class + '">' +
'<td class="otable__id"><a href="">' + id + '</a></td>' +
'<td class="otable__site"><a href="/Customer/FDGOrders.aspx?oid=' + id + '">' + site + '</a></td>' +
'<td class="otable__by"><a href="">' + patient + '</a></td>' +
'<td class="otable__insurance otable__priority--' + priority + '" data-sort-value="' + insurance_sort_val + '"><a href="">' + insurance_co + '</a></td>' +
'<td class="otable__date" data-sort-value="' + received_date + '"><a href="">' + received_datestring + '</a></td>' +
'<td class="otable__date" data-sort-value="' + exam_date + '"><a href="">' + exam_datestring + '</a></td>' +
'<td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + exam_date + '"><a href="">' + status_name + '</a></td>' +
'<td class="otable__date--wide" data-sort-value="' + updated_date + '"><a href="">' + updated_datestring + ' ' + updated_timestring + '</a></td>' +
'</tr>');
$row.find('a').on('click', function (e) {
if (!$(this).parent('.otable__site').length) {
e.preventDefault();
showDialog('/Customer/FDGPatientOrder.aspx?oid=' + id + '&poid=' + poid);
}
if ($(this).parent('.otable__site').length) {
e.preventDefault();
showDialog('/CustomerProfile.aspx?cid=' + custid);
}
});
}
// Append to table body
$table.find('tbody').append($row);
});
}
// Fire event
//$table.trigger('all-rows-added');
//$table.off('all-rows-added');
// Table sorting functionality
if (table_role == 'pending') {
initTableSorting($table, 7);
} else if (table_role == 'preauth') {
initTableSorting($table, 3);
}
// Status filter functionality
var $list = $table.find('.otable__status__list');
// Clear previous filters
$list.find('ul>li:not(:first)').remove();
// Loop through statuses to see which are contained in the table
$.each(statuses, function (key, value) {
if ($table.find('tbody').has('.otable__status[data-status-id="' + value.id + '"]').length > 0) {
var $li;
if (table_role == 'pending') {
$li = $('<li>' +
'<button data-filter="' + value.id + '" data-color="' + value.color + '">' +
'<div class="otable__legend"></div>' +
value.name +
'</button>' +
'</li>');
} else {
$li = $('<li>' +
'<button data-filter="' + value.id + '">' +
'<div class="otable__legend"></div>' +
value.name +
'</button>' +
'</li>');
}
// Add the list item
$li = $li.appendTo($list.find('ul'));
// Set the legend color
var $btn = $li.find('button'),
filter = $btn.data('filter'),
color = $btn.data('color');
if (color !== null) {
$li.find('.otable__legend').css('background', color);
}
}
});
$th.on('click', function (e) {
// Check if main filter is being clicked, otherwise don't sort
if ($list.has(e.target).length > 0) {
var $target = $(e.target).closest('button'),
filter = $target.data('filter');
// Sort all rows by ascending status
$table.find('th').eq(7).stupidsort('asc');
// Style actively selected item
$list.find('li').removeClass('otable__status__checked');
$target.parent('li').addClass('otable__status__checked');
if (filter == 'all') {
$table.find('tbody > tr').css('display', 'table-row');
} else {
$table.find('tbody > tr').css('display', 'none');
$table.find('tbody > tr').has('.otable__status[data-status-id="' + filter + '"]').css('display', 'table-row');
}
// Force hide list when option clicked
$list.css({
'clip': 'rect(0 0 0 0)',
'opacity': 0
});
// Restore default behavior once mouse is moved
$table.mousemove(function () {
$list.removeAttr('style');
});
// Prevent main sorting action
return false;
}
});
// Sticky table header
$table.stickyTableHeaders();
// Remove loading indicator
$table.find('.otable__loading').css('display', 'none');
}
}).fail(function (jqxhr,
我们遇到了类似的场景,我们有超过 30000 条记录要在同一页面上呈现,API 表现良好,但 UI 在性能方面变得可怜。Chrome 和 Firefox 以某种方式幸存下来,并以 10 到 15 秒的延迟呈现记录,但 IE 是一场噩梦,每次我们访问该页面时,浏览器都会冻结。这个问题的解决方案是渐进但优雅的,我们必须转向基础知识。我将在这里分解我的解决方案的一个子集
将$.eachand_.each循环替换为本机for(var i = 0; i < lenght; i += 1)循环。这样做大大提高了性能。为了证明这个概念,当时我创建了一个 jsperf(查看此处)性能基准测试,它显示出巨大的性能提升。例如,在您的情况下,将$.each(dataSet, function (key, value) {and替换$.each(statuses, function (key, value) {为本机 for 循环。请参阅此图片比较循环

减少 JQuery 选择器的数量也被证明是有益的,而不是创建像 之类的内存 jquery 元素$('<div>bla bla bla</div>');,而是使用字符串连接,最后使用 example$el.html()被证明是非常有效的。在你的例子中,你不需要做类似的事情$row = $('<tr class ...,然后绑定函数$row.find('a').on('click',你只需要创建一个长字符串并附加其中的所有内容,最后将该长字符串附加到 DOM。如果您只是这样做以将单击事件绑定到每一行(OMG),则可以通过使用 JQuery 在单击父级并将子级作为过滤器时实现类似的行为,例如$('table').on('click', 'tr', myClickFunc);。这将仅绑定单个单击事件而不是数千个单击事件,从而带来巨大的性能提升。
$.grepor$.map或$.filter等)并使用本机循环,也带来了巨大的改进。splitDate获取一个数组并返回一个数组,而不是多个方法调用。因此,这只是您可以采取的改善加载时间和渲染性能的直接措施的简要总结。
一个更重要的提示是,您还应该检查来自服务器的响应的大小,如果它很大并且以兆字节为单位,那么您还必须优化您的 API,并且只向 UI 提供它需要的东西,不要提供过多的东西,因为它会减慢用户界面的速度。