jqgrid datatype为local时 reloadGrid数据排序 耗时性能慢问题解决

  jqgrid是一个比较好的开源表格编辑工具,最近在使用时碰到一个问题,通过调用jqGrid().trigger(‘reloadGrid’)实现数据排序时,出现页面卡顿,响应慢问题,后来使用jqery Dom操作将需要排序的表格行tr移到tbody最后实现。

1、问题描述

页面截图:
在这里插入图片描述
处理标记为1的排在表格最后
在这里插入图片描述
页面只是实际项目的一个仿制页面,数据显示、按钮操作已经做了一些处理,原始操作如下:
1)这是个成品扫码出库页面;
2)每次扫码时,扫到的二维码表格行,会标记为已处理,并移到表格最后面;
3)实际操作中,当数据量超过200条的时候,扫描枪扫码后页面要等很久才能响应完,才能进行下个扫码操作。

当初代码实现
1)jgGrid构建时,默认flag升序排序:sortname: ‘flag’, sortorder: ‘asc’,
2)获取表格数据,jqGrid(“getRowData”),遍历找到二维码对应的行记录;
3)将该行记录, 已处理标记:flag设置为1;
4)调用jqGrid().trigger(‘reloadGrid’),会跟进flag进行重新排序,flag为1的都排在表格后面。

POC 页面代码

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<title>jggrid大数据排序优化</title>
	
	<link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
	<link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.5.0/css/font-awesome.min.css" />
	<link rel="stylesheet" href="https://cdn.bootcss.com/jqgrid/4.6.0/css/ui.jqgrid.css" />
	<script src="https://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
	<script src="https://cdn.bootcss.com/jqgrid/4.6.0/js/jquery.jqGrid.min.js"></script>
</head>
<body>
<div class="page-content">
	<div class="page-head clearfix form-horizontal"> <!-- page-head -->
		<div class="form-group form-group-sm form-group-np clearfix">
			<button type="button" class="btn btn-sm btn-azure" onclick="setFlag()">设置已处理</button>
			<button type="button" class="btn btn-sm btn-azure" onclick="setAndReload()">设置已处理, jqGrid排序</button>
			<button type="button" class="btn btn-sm btn-azure" onclick="setAndDom()">设置已处理, jqDom操作排序</button>
		</div>		
	</div><!-- page-head -->
	<div class="page-body"> <!-- page-body -->
		<div class="panel panel-default" id="panel-orders">
			<table id="orders"></table>
		</div>	
	</div>
</div>
   
<script type="text/javascript">
	var data = [];
	function getBills() {
		for (var i = 0; i < 1000; i ++) {
			data.push({
				sid: i,
				bill_id: i,
				bill_detail: i,
				goods_id: i,
				unit_id: i,
				package_id: i,
				ref_detail: i,
				goods_no: 10000 + i,
				goods_name: '零件名称' + 1000 + i,
				car_type_name: '车型' + 1000 + i,
				package_name: '包装器具' + 1000 + i,
				unit_name: '单位',
				snp: 0.89,
				box_count: 1000 + i,
				total_count: 1000 + i,
				goods_count: 1000 + i,
				out_count: 1000 + i,
				bill_no: 'BN0000000' + i,
				qrcode: '1000000000' + i,
				barcode: '1000000000' + i,
				flag:  i >= 999 ? 1 : 0,
			})
		}
		$("#orders").jqGrid("clearGridData").jqGrid('setGridParam',{data: data || []}).trigger('reloadGrid');
	}
	
	function setFlag() {
		var rowIds = $("#orders").jqGrid("getGridParam", "selarrrow");
		if(rowIds.length < 1) {
			alert('请先选择行记录!'); return rowIds;
		}
		for (var i = 0, l = rowIds.length; i < l; i++) {
			$("#orders").jqGrid("setCell", rowIds[i], 'flag', 1);
			// 
			// $("#orders").jqGrid("setRowData", rowIds[i], 'flag', 1);
			var rowData = $("#orders").jqGrid("getRowData", rowIds[i]);
			rowData.flag = 1;
			$("#orders").jqGrid("setRowData", rowIds[i], rowData);
		}
		$("#orders").jqGrid('resetSelection');
		return rowIds;
	}
	
	function setAndReload() {
		setFlag();
		//
		var stime = new Date();
		$("#orders").jqGrid().trigger('reloadGrid');
		console.log('sort time: ', new Date().getTime() - stime.getTime());
	}
	
	function setAndDom() {
		var rowIds = setFlag();
		//
		var stime = new Date();
		var $tbody = $("#orders tbody");
		for (var i = 0, l = rowIds.length; i < l; i++) {
			$("#" + rowIds[i]).appendTo($tbody);
		}
		console.log('sort time: ', new Date().getTime() - stime.getTime());
	}
	
	function flagFmt(data, type, row) {
		return row.flag == "1" ? "<div style='background-color:green; color:white'>Y<div>" : "N";
	}
	$(function() {
		$("#orders").jqGrid({
			colModel: [
				{label: "Y/N", name: null, width: 60, align:'center', formatter: flagFmt},
				{label: "处理标记", name: "flag", width: 60, hidden:false},
				{label: "零件号", name: "goods_no", width: 60},
				{label: "零件名称", name: "goods_name", width: 180},
				{label: "车型", name: "car_type_name", width: 70},
				{label: "包装器具", name: "package_name", width: 70},
				{label: "单位", name: "unit_name", width: 40},
				{label: "装箱率", name: "snp", width: 50, sorttype: "number"},
				{label: "箱数", name: "box_count", width: 40, sorttype: "number"},
				{label: "需求总数", name: "total_count", width: 70, sorttype: "number"},
				{label: "需求数量", name: "goods_count", width: 70,},
				{label: "出库数量", name: "out_count", width: 70, sorttype: "number"},
				{label: "订单号", name: "bill_no", width: 150},
				{label: "二维码", name: "qrcode", width: 130},
				{label: "条码", name: "barcode", width: 220}
			],
			datatype: 'local',
			rownumbers: true,
			multiselect: true,
			sortname: 'flag',
			sortorder: 'asc',
			height: 500,
			rowNum: 1000
		});
		getBills();
	});
</script>
</body>
</html>

2、页面操作描述

1)“设置已处理” 按钮,设置选中行的处理标记 = 1;
2)“设置已处理, jqGrid排序” 按钮,设置选中行的处理标记 = 1,并且调用jqGrid().trigger(‘reloadGrid’)进行数据排序,代码见setAndReload();
3)“设置已处理, jqDom操作排序” 按钮,设置选中行数据的处理标记 = 1,并且使用jquery进行dom操作,将处理标记 = 1的tr移到tbody最后,代码见setAndDom();
4)表格的Y/N列为处理标记的formatter列,处理标记 = 1显示绿底白字Y,否则显示白底黑字N

3、2种排序处理方式性能比较

数据行 reloadGrid排序 耗时(毫秒) jquery dom操作 耗时(毫秒)
100 66 1
200 116 1
500 261 1
1000 412 2

猜你喜欢

转载自blog.csdn.net/chuangxin/article/details/83706893
今日推荐