【问题标题】:jqGrid Taking Long Time For Large RecordsjqGrid 需要很长时间来处理大型记录
【发布时间】:2014-10-21 00:09:20
【问题描述】:

我正在使用 jgGrid。它工作得很好,但是当我通过大约 90,000 条记录并在谷歌浏览器中打开页面时,创建一个网格大约需要 8 秒,在我的情况下它应该接近 3-4 秒。此外,当我在 IE 上运行同一页面时,它变得无响应。

有什么建议可以减少时间吗?

我的脚本

function GetCommodityGrid(array) {
 array = array.rows; // assign rows array to array object
totalRows = array.length;
    jQuery(document).ready(function () {
        jQuery("#list").jqGrid({
            datatype: 'local',
            data: array,
            colNames: ['COM_NAME', 'COM_CODE', 'DELV_UNITS', 'LOT_SIZE', 'TICK_SIZE', 'TICK_VALUE'],
            colModel: [
        { name: 'COM_NAME', index: 'COM_NAME', width: 90, editable: true },
        { name: 'COM_CODE', index: 'COM_CODE', width: 100, editable: true },
        { name: 'DELV_UNITS', index: 'DELV_UNITS', width: 80, align: "right", editable: true },
        { name: 'LOT_SIZE', index: 'LOT_SIZE', width: 80, align: "right", editable: true },
        { name: 'TICK_SIZE', index: 'TICK_SIZE', width: 80, align: "right", editable: true },
        { name: 'TICK_VALUE', index: 'TICK_VALUE', width: 150, sortable: false, editable: true }
    ],

            rowList: [50,100,200],
            rownumbers: true, // show the numbers on rows
            loadonce: true,
            pager: '#pager',
            sortname: 'COM_NAME',
            viewrecords: true, // show the total records on the end of the page
            editurl: "TestGrid/EditRecord",
            caption: "JSON Example",

            //new option

           gridview: true,
           autoencode: true,

        });


        $("#list").jqGrid("navGrid", "#pager", { add: false },
    { //the Edit options
        closeAfterEdit: true,
        afterSubmit: function (response) {
            // you should return from server OK in sucess, any other message on error
            alert("after Submit");
            if (response.responseText == "OKK") {
                alert("Update is succefully")
                return [true, "", ""]
            }
            else {
                alert("Update failed")
                $("#cData").click();
                return [false, "", ""]
            }
        }
    });



    });
}

【问题讨论】:

  • 可能还有其他一些回调(loadCompletegridCompleate 您没有在此处发布)?
  • @Oleg 不,我没有订阅任何加载完成或网格完成事件。
  • 查看我的回答的更新部分。

标签: javascript jquery internet-explorer google-chrome jqgrid


【解决方案1】:

尝试按需加载JqGrid,即一次加载较小的数据块而不是所有数据,并在分页时加载剩余数据。

这是一个示例代码供参考

PHP 与 MySQL

...
$page = $_GET['page']; // get the requested page

$limit = $_GET['rows']; // get how many rows we want to have into the grid

$sidx = $_GET['sidx']; // get index row - i.e. user click to sort

$sord = $_GET['sord']; // get the direction

if(!$sidx) $sidx =1;

// connect to the database    
$db = mysql_connect($dbhost, $dbuser, $dbpassword)
or die("Connection Error: " . mysql_error());    

mysql_select_db($database) or die("Error conecting to db.");

$result = mysql_query("SELECT COUNT(*) AS count FROM invheader a, clients b WHERE a.client_id=b.client_id");

$row = mysql_fetch_array($result,MYSQL_ASSOC);

$count = $row['count'];    

if( $count >0 ) {
    $total_pages = ceil($count/$limit);
} else {
    $total_pages = 0;    
}

if ($page > $total_pages) $page=$total_pages;

$start = $limit*$page - $limit; // do not put $limit*($page - 1)

if ($start<0) $start = 0;

$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id ORDER BY $sidx $sord LIMIT $start , $limit";

$result = mysql_query( $SQL ) or die("Couldnt execute query.".mysql_error());

$responce->page = $page;

$responce->total = $total_pages;

$responce->records = $count;

$i=0;

while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {

    $responce->rows[$i]=$responce->rows[$i]['cell']=array($row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]);

    $i++;
} 

echo $json->encode($responce); // coment if php 5
//echo json_encode($responce);
...

【讨论】:

  • 但我的要求是一次获取所有数据。
【解决方案2】:

我分析了加载包含 90,000 行未排序行的本地网格的过程,发现了非常有趣的瓶颈,可以轻松克服。首先here 是运行速度很快的demo,here 是几乎相同的demo,尤其是在IE 中运行很慢。

最开始加载jqGrid的时候直接得到jqGrid代码的the line

var p = $.extend(true,{
    // there are here different default values of jqGrid parameters
}, $.jgrid.defaults, pin || {});

因为使用true 作为第一个参数,所以 jQuery 制作了数据的完整副本并且它运行缓慢(为什么?这是另一个纯粹的 jQuery 问题)。

作为一种解决方法,我建议在创建网格时不设置data 参数。在这种情况下,将使用默认参数data: []。而不是那个可以在onInitGrid回调中设置data

$("#list").jqGrid({
    //data: gridData,
    datatype: "local",
    ....
    onInitGrid: function () {
        // get reference to parameters
        var p = $(this).jqGrid("getGridParam");

        // set data parameter
        p.data = gridData;
    }
});

因此网格的加载性能会变得更好。

稍后我将向 trirand 发布我的建议,如何在案例中对 jqGrid 的代码进行小的更改以提高 jqGrid 的性能。我的建议很简单。可以将data参数保存在一个变量中,然后调用var p = $.extend(true,{...});,然后在p变量中直接设置data参数

    // save local data array in temporary variable and remove from input parameters
    // to improve performance
    var localData;
    if (pin != null && pin.data !== undefined) {
        localData = pin.data;
        pin.data = [];
    }
    var p = $.extend(true,{
        // there are here different default values of jqGrid parameters
    }, $.jgrid.defaults, pin || {});
    if (localData !== undefined) {
        p.data = localData;
    }

The demo 使用the fixed code of jqGrid,而且效果很快。

更新:我发布到 trirand 的 The pull request 已经是 merged 到 github 上 jqGrid 的主要代码(在 the bug report 中查看更多信息)。所以jqGrid的下一个版本(4.6.0以上的版本)就不会出现上述问题了。

【讨论】: