When I display a small amount per page, it's quick and very good. When I increase it to 100 or more it starts getting slow. At 1000 it's unbearable! This is the code used for drawing the grid:
$("#stSearchTermsGrid").jqGrid({
mtype: "POST",
postData:{},
datatype: function(postdata) {
$.ajax({
url: 'ajax/ajax_termsSearchGridSimple.php',
data: postdata,
async: false,
dataType: "xml",
error: function(){
alert('Error loading XML document');
},
success: function(data,stat,xmldata){
//check error
var $error=$(data).find('error').text();
if($error!="0")
{
messageBox("Error",$error);
return;
}
//content
var $content=$(data).find('content').text();
if($content!="0")
{
var thegrid = $("#stSearchTermsGrid")[0];
thegrid.addXmlData(xmldata.responseXML);
}
}
});
},
colNames:["tId","term", "revTerm", "uType","freq","description","fId","facet","modifiedTime"],
colModel:[
//tId
{name:'tId',index:'tId',align:"center",searchoptions:{sopt:['eq','ne','lt','le','gt','ge','in','ni']}},
//term (editable)
{name:'term',index:'term',searchoptions:{sopt:['eq','ne','in','ni','bw','bn','ew','en','cn','nc']},editable:true,edittype:'text',editoptions:{size:20},editrules:{required:true},formoptions:{elmsuffix:'(*)'}},
//revTerm (editable)
{name:'revTerm',index:'revTerm',searchoptions:{sopt:['eq','ne','in','ni','bw','bn','ew','en','cn','nc']},editable:true,edittype:'text',editoptions:{size:20},editrules:{required:true},formoptions:{elmsuffix:'(*)'}},
//uType (editable)
{name:'uType',index:'uType',align:"center",searchoptions:{sopt:['eq','ne','in','ni']},editable:true,edittype:'select',editoptions:{value:{'':'any','NPU':'proper noun','NU':'noun','VU':'verb'}}},
//freq
{name:'freq',index:'freq',align:"center",searchoptions:{sopt:['eq','ne','lt','le','gt','ge','in','ni']}},
//description (editable)
{name:'description',index:'description',searchoptions:{sopt:['bw','bn','ew','en','cn','nc']},editable:true,edittype:'textarea',editoptions:{rows:"3"}},
//fId
{name:'fId',index:'fId',align:"center",searchoptions:{sopt:['eq','ne','lt','le','gt','ge','in','ni']}},
//facet
{name:'facet',index:'facet',searchoptions:{sopt:['eq','ne','in','ni','bw','bn','ew','en','cn','nc']}},
//modifiedTime
{name:'modifiedTime',index:'modifiedTime',align:"center",searchoptions:{sopt:['eq','ne','lt','le','gt','ge','bw','bn','ew','en','cn','nc']}}
],
gridComplete: function(){
var $ids=$("#stSearchTermsGrid").jqGrid('getDataIDs');
for($i=0;$i<$ids.length;$i++){
var $reference="<a href='javascript:void();' onclick=\"toGoogle('stSearchTermsGrid','"+$ids[$i]+"');\">G</a>";
//update columns
$("#stSearchTermsGrid").jqGrid('setRowData',$ids[$i],{"reference":$reference});
//coloring the recently classified row
var $colorRecentlyModified = '#DFFC91';
var modifiedTime = $("#stSearchTermsGrid").jqGrid('getCell',$ids[$i],'modifiedTime');
var timeDiff = Math.abs(new Date() - new Date(modifiedTime.replace(/-/g,'/')));
// 86400000 is the number of milliseconds in one day. Multiplying by days to mark the ones which are modified a few days ago
timeLimit = 86400000 * 1.5;
if(timeDiff < timeLimit)
{
for(colN=2; colN<9; colN++)
$("#stSearchTermsGrid").jqGrid('setCell', $ids[$i], colN, '', {'backgroundColor':$colorRecentlyModified});
}
//coloring the unclassified row
var $colorUnclassified = '#FFCECE';
var $fId = $("#stSearchTermsGrid").jqGrid('getCell',$ids[$i],'fId');
if($fId == "0")
{
for(colN=2; colN<9; colN++)
$("#stSearchTermsGrid").jqGrid('setCell', $ids[$i], colN, '', {'backgroundColor':$colorUnclassified});
}
}
},
sortable: true,
//autowidth:true,
width: 900, //width for grid
height: 250, //height for grid
sortname: 'term', //default sort column
caption: "Terms", //caption for grid (empty will hide)
hidegrid: false,
gridview: true, //load the grid more fast
multiselect: true, //support mulitselect
//multiboxonly: true,
pager: '#stSearchTermsGridPager',
rowNum:10,
rowList:[10,25,50,100,500,1000],
viewrecords: true, //show view record information
viewsortcols: [true,'vertical',true], //show sortable column with icons
editurl: 'ajax/ajax_termsEdit.php'
});
$("#stSearchTermsGrid").jqGrid('navGrid','#stSearchTermsGridPager',
{edit:true,add:false,del:true,search:true,view:true,refresh:true},
// edit options
{
onclickSubmit : function(params, posdata) {
var $tId=$("#stSearchTermsGrid").jqGrid('getGridParam','selrow');
if($tId && $tId.length>0)
{
var $rowAry=$("#stSearchTermsGrid").jqGrid('getRowData',$tId);
var $fId=$rowAry["fId"];
return {"fId":$fId}
}
},
afterSubmit : gridAfterSubmit,
reloadAfterSubmit: true,
closeOnEscape:true,
bottominfo:"Fields marked with (*) are required."
},
// add options
{},
//del options
{
msg: "Selected records(s) will be permanently deleted and cannot be recovered.<br/> Are you sure?",
afterSubmit : gridAfterSubmit,
reloadAfterSubmit: true,
closeOnEscape:true
},
// search options
{multipleSearch:true,closeOnEscape:true},
//view options
{
closeOnEscape:true
}
);
$("#stSearchTermsGrid").jqGrid('gridResize',{minWidth:900,maxWidth:2000,minHeight:250, maxHeight:1000});
I see many places where the grid can be improved.
1) You should use paging. If you show the user 1000 rows of data, the data will be not displayed on the monitor at once. The user have to scroll the windows of web browser to see the most parts of data. Which sense has to spend time to paint the parts of window which will not be seen? The scrolling of data with respect of jqGrid is much more effective as scrolling of browser window. Moreover no person are able to analyse the 1000 rows of data. He have to change sorting and set different filters to understand which from the data are interesting for him. It is one more argument for the data paging and implemented some searching. It you already use advanced searching you can consider to use additionally toolbar searching with the parameter
stringResult:true
which is compatible with the advanced searching.2) you should rewrite the code of
gridComplete
totally. I suppose, that for relatively large number of rows the function is the bottleneck of your code. To verify this just temporary comment the function and compare the time of the grid painting. You should understand that every time you get data by id or set data by id jQuery will have to search the DOM element by id. Especially modification of data on the page can be very slow. By the way it seems to me that you set the same 'background-color' (what is 'backgroundColor' ???) CSS style for almost the whole cells of the rows. Why not set the 'background-color' for the row (<tr>
element) instead?3) I strictly recommend you not use
datatype
as function. Your server part should return some error HTTP code. In the case the loadError event will work and you can decode and display the custom error message. All other in your data seems be standard and you need not usedatatype
as function. If you will usedatatype:"xml"
you can for example try to useloadonce:true
and implement client-side data paging and sorting if you will have problem with implementation of this features on the server.I don't want to write too long text so I stop on the 3 most important points. By the way if you will switch from XML to JSON as the datatype used for the communication with the server, it will also improve a little the performance.
UPDATED: To see the performance of jqGrid with 1000 rows of data without paging and with data paging look at the links. Is by the way the performance of my example with 1000 rows without paging also so slow as in your case?