2 votes

Pourquoi jqGrid est très lent lorsque le nombre de lignes affichées augmente ?

Lorsque j'affiche une petite quantité par page, c'est rapide et très bon. Lorsque j'augmente à 100 ou plus, cela commence à devenir lent. À 1000, c'est insupportable ! Voici le code utilisé pour dessiner la grille :

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

15voto

Oleg Points 136406

Je vois de nombreux endroits où la grille peut être améliorée.

1) Vous devez utiliser radiomessagerie . Si vous montrez à l'utilisateur 1000 lignes de données, les données ne seront pas affichées sur le moniteur. en même temps . L'utilisateur doit faire défiler les fenêtres du navigateur web pour voir la plupart des données. Quel sens doit passer du temps à peindre les parties de la fenêtre qui ne seront pas vues ? Le défilement des données avec jqGrid est le suivant beaucoup plus efficace comme le défilement de la fenêtre du navigateur. De plus, personne n'est capable d'analyser les 1000 lignes de données. Elle doit changer le tri et définir différents filtres pour comprendre quelles données sont intéressantes pour elle. C'est un argument de plus pour la pagination des données et la mise en œuvre de certaines recherches. Si vous utilisez déjà la recherche avancée, vous pouvez envisager de l'utiliser en plus. recherche par barre d'outils avec le paramètre stringResult:true qui est compatible avec le recherche avancée .

2) vous devriez réécrire le code de gridComplete totalement . Je suppose que pour un nombre relativement important de lignes la fonction est le goulot d'étranglement de votre code. Pour le vérifier, il suffit de commenter temporairement la fonction et de comparer l'heure de la peinture de la grille. Vous devez comprendre que chaque fois que vous obtenez des données par id ou définissez des données par id, jQuery devra rechercher l'élément DOM par id. En particulier, la modification des données sur la page peut être très lente. Par ailleurs, il me semble que vous définissez le même style CSS 'background-color' (qu'est-ce que 'backgroundColor' ? ??) pour presque toutes les cellules des lignes. Pourquoi ne pas définir la "couleur de fond" pour la ligne ( <tr> ) à la place ?

3) Je vous recommande strictement de ne pas utiliser datatype en tant que fonction. Votre partie serveur devrait retourner un code d'erreur HTTP . Dans le cas où le loadError fonctionnera et vous pourrez décoder et afficher le message d'erreur personnalisé. Tous les autres éléments de vos données semblent être standard et vous n'avez pas besoin d'utiliser la fonction datatype comme fonction. Si vous utilisez datatype:"xml" vous pouvez par exemple essayer d'utiliser loadonce:true et mettre en œuvre la pagination et le tri des données côté client si vous avez des difficultés à mettre en œuvre ces fonctionnalités sur le serveur.

Je ne veux pas écrire un texte trop long donc je m'arrête sur les 3 points les plus importants. A propos, si vous passez de XML à JSON comme type de données utilisé pour la communication avec le serveur, cela améliorera aussi un peu les performances.

MISE À JOUR : Pour voir les performances de jqGrid avec 1000 lignes de données sans radiomessagerie y avec pagination des données Regardez les liens. Au fait, les performances de mon exemple avec 1000 lignes sans pagination sont-elles aussi lentes que dans votre cas ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X