Почему jqGrid работает очень медленно, когда количество отображаемых строк увеличивается? - PullRequest
2 голосов
/ 11 февраля 2011

Когда я показываю небольшое количество на странице, это быстро и очень хорошо.Когда я увеличиваю его до 100 или больше, он начинает замедляться.На 1000 это невыносимо!Это код, используемый для рисования сетки:

 $("#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});

1 Ответ

15 голосов
/ 11 февраля 2011

Я вижу много мест, где можно улучшить сетку.

1) Вы должны использовать paging . Если вы покажете пользователю 1000 строк данных, данные не будут отображаться на мониторе сразу . Пользователь должен прокрутить окна веб-браузера, чтобы увидеть большую часть данных. Какой смысл тратить время на покраску частей окна, которые не будут видны? Прокрутка данных относительно jqGrid гораздо эффективнее , чем прокрутка окна браузера. Более того, ни один человек не может проанализировать 1000 строк данных. Он должен изменить сортировку и установить разные фильтры, чтобы понять, какие из данных ему интересны. Это еще один аргумент для подкачки данных и реализован некоторый поиск. Если вы уже используете расширенный поиск, вы можете дополнительно использовать поиск на панели инструментов с параметром stringResult:true, который совместим с расширенным поиском .

2) вам следует переписать код gridComplete полностью . Я полагаю, что для относительно большого количества строк функция является узким местом вашего кода. Для проверки просто временно закомментируйте функцию и сравните время покраски сетки. Вы должны понимать, что каждый раз, когда вы получаете данные по идентификатору или устанавливаете данные по идентификатору, jQuery должен будет искать элемент DOM по идентификатору. Особенно изменение данных на странице может быть очень медленным. Между прочим, мне кажется, что вы устанавливаете один и тот же стиль CSS background-color (что такое backgroundColor ???) для почти всех ячеек строк. Почему бы не установить цвет фона для строки (<tr> элемент) вместо этого?

3) Я настоятельно рекомендую не использовать datatype в качестве функции. Ваша серверная часть должна вернуть HTTP-код error . В случае, если событие loadError будет работать, вы можете декодировать и отобразить пользовательское сообщение об ошибке. Все остальное в ваших данных кажется стандартным, и вам не нужно использовать datatype в качестве функции. Если вы будете использовать datatype:"xml", вы можете, например, попытаться использовать loadonce:true и реализовать подкачку и сортировку данных на стороне клиента, если у вас возникнут проблемы с реализацией этих функций на сервере.

Я не хочу писать слишком длинный текст, поэтому я остановлюсь на 3 самых важных моментах. Кстати, если вы переключитесь с XML на JSON в качестве типа данных, используемого для связи с сервером, это также немного улучшит производительность.

ОБНОВЛЕНО: Чтобы увидеть производительность jqGrid с 1000 строками данных без подкачки и с подкачкой данных , посмотрите ссылки. Кстати, производительность моего примера с 1000 строками без подкачки также медленная, как в вашем случае?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...