2

I have 4 grid tables. They use the same modal. I cannot use the same store as each grid has to send a parameter value to get the data from db. So, what's happening is I ended up making 4 different stores and then when I load my application, it lags because it waits to load all the 4 stores. this is my grid.. so I have 3 more grids like this

this.grid1 =Ext.create('Ext.grid.Panel',{
    title:'GridView App',        store: store,        loadMask:true,
    columns:[
       { header:'Q1',            sortable:true, dataIndex:'Q1', flex:1,},
       { header:'Q2',            sortable:true, dataIndex:'Q2', flex:1,},
       { header:'Q3',            sortable:true, dataIndex:'Q3', flex:1,},
       { header:'Q4',            sortable:true, dataIndex:'Q4', flex:1,}

and this is my store1... and similarly I have 3 more stores like this each with parameter Q2, Q3, Q4 respectively

 var store1 =Ext.create('Ext.data.JsonStore',{
    storeId:'myData',        scope:this,
    fields:[
       { name:'Q1', type:'int'},
       { name:'Q2', type:'int'},
       { name:'Q3', type:'int'},
       { name:'Q4', type:'int'}
   ],        
    sorters:[{            property:'Q1',            direct:'ASC'}],        
    proxy:{            
          type:'ajax',            
          url:'GridView/writeRecord',            
          extraParams: { ID: Q1 },            
          reader: newExt.data.JsonReader({                
               root:'myTable',              
               totalProperty:'count'
           })
       }
 });

Is there a faster/better way to implement it than the way that I have?

UPDATE - enter image description here

SECOND UPDATE -

Here is my layout for the whole application... my rightcontainer is disabled at first and contains the actual grids and forms, and click on the item on tab enables the rightcontainer and loads all the grid.

Ext.define('ExtjsApp.app1.appPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.mypanel',
layout: {
    type: 'vbox',
    align: 'stretch'
},
scope: this,
titleAlign: 'center',
minWidth: 900,
bodyPadding: 10,
requires: [],
items: [],
constructor: function () {
    this.callParent(arguments);
    this.regForm = Ext.create('ExtjsApp.app1.RegForm', {});

    leftTreeStore = Ext.create('Ext.data.TreeStore', {
        scope: this,
        storeId: 'leftTreeStore',
        fields: [
            { name: 'text', type: 'string' },
            { name: 'dataId', type: 'string' },
            { name: 'listName', type: 'string' },
            { name: 'leaf', type: 'bool' }
        ],
        root: { expanded: true },
        proxy: {
            type: 'ajax',
            url: 'app1/getRecords',
            extraParams: { organization: 'GOOGLE' },
            reader: { type: 'json' }
        },
        autoLoad: true,
        expanded: true,
        autoSync: true,
        listeners: {
        }
    });

    allRecordsStore = Ext.create('Ext.data.TreeStore', {
        id: 'allRecordsStore',
        autoLoad: false,
        autoSync: false,
        scope: this,
        fields: [
            { name: 'text', type: 'string' },
            { name: 'dataId', type: 'string' },
            { name: 'listName', type: 'string' },
            { name: 'leaf', type: 'bool' }
        ],
        root: { expanded: true },
        proxy: {
            type: 'ajax',
            url: 'app1/getRecords',
            extraParams: { organization: 'GOOGLE' },
            reader: { type: 'json' }
        }
    });

    this.currentMonthsTree = Ext.create('Ext.tree.TreePanel', {
        scope: this,
        title: 'Current 12 Months',
        titleAlign: 'center',
        tabIndex: 0,
        height: 500,
        flex: 1,
        rootVisible: false,
        store: leftTreeStore,
        id: 'currentMonthsTree',
        useArrows: true,
        hideHeaders: true,
        columns: [
            {
                xtype: 'treecolumn',
                id: 'ID',
                dataIndex: 'text',
                flex: 1
            }
        ],
        viewConfig: {
            plugins: {
                ptype: 'treeviewdragdrop',
                enableDrop: false,
                appendOnly: false,
                enableDrag: false
            },
            listeners: {
                itemclick: function (view, rec, item) {
                    if (rec.isLeaf()) {
                        alert('isLeaf');
                    }
                    else if (!rec.isLeaf()) {
                        alert('isNotLeaf');
                    }
                }
            },
            allowCopy: true,
            copy: true
        }
    });

    this.currentMonthsTree.on('selectionchange', function (selected) {
        FnDisplayRecord(selected.selected.items[0]);
    });

    this.allRecordsTree = Ext.create('Ext.tree.TreePanel', {
        scope: this,
        title: 'All Records',
        titleAlign: 'center',
        flex: 1,
        tabIndex: 1,
        rootVisible: false,
        store: allRecordsStore,
        id: 'allRecordsTree',
        useArrows: true,
        hideHeaders: true,
        columns: [
            {
                xtype: 'treecolumn',
                id: 'ID',
                dataIndex: 'text',
                flex: 1
            }
        ],
        viewConfig: {
            plugins: {
                ptype: 'treeviewdragdrop',
                enableDrop: false,
                enableDrag: false,
                appendOnly: false
            },
            listeners: {
                itemclick: function (view, rec, item) {
                    if (rec.isLeaf()) {
                        alert('isLeaf');
                    }
                    else if (!rec.isLeaf()) {
                        alert('isNotLeaf');
                    }
                }
            },
            allowCopy: true,
            copy: true
        }
    });

    this.allRecordsTree.on('selectionchange', function (selected) {
        FnDisplayRecord(selected.selected.items[0]);
        //alert('Hello');
    });

    function FnClearValues() {
        //Clear All Values
        alert('ClearALLValues');
    }

    function FnSetValues(myObj) {
        //I set all my form values using Ext.getCmp
        Ext.getCmp('Textl').setValue(myObj.Text1);
    }


    function FnDisplayRecord(row) {
        if (row.get('leaf') == true) {
            console.log(row.data.dataId);
            var tempID = row.data.dataId;
            Ext.getCmp('rightContainer').setLoading(true, true);
            Ext.getCmp('requisitionPOGridPanel').store.loadData([], false);

            Ext.Ajax.request({
                method: 'GET',
                url: 'app1/getRecord',
                headers: { 'Content-Type': 'application/json' },
                dataType: 'json',
                params: {
                    ID: tempID
                },
                success: function (response) {
                    Ext.getCmp('rightContainer').setLoading(false, false);
                    myObj = Ext.JSON.decode(response.responseText);
                    if (AsbestosObj.DateIssued != '') {
                        FnSetValues(AsbestosObj);
                        Ext.getCmp('GridPanel').store.load({ params: { ID: tempID} });
                        Ext.getCmp('Grid1').store.load({ params: { ID: tempID, qID: 'Q01'} });
                        Ext.getCmp('Grid2').store.load({ params: { ID: tempID, qID: 'Q02'} });
                        Ext.getCmp('Grid3').store.load({ params: { ID: tempID, qID: 'Q03'} });
                        Ext.getCmp('Grid4').store.load({ params: { ID: tempID, qID: 'Q04'} });
                    }
                    else { FnClearValues(); }
                },
                failure: function () {
                    Ext.Msg.alert('Message', 'Error');
                }
            });
        }
        else if (row.get('leaf') == false) {
            FnClearValues();
        }
    }

    this.rightContainer = Ext.create('Ext.form.Panel', {
        scope: this,
        id: 'rightContainer',
        layout: {
            type: 'vbox',
            align: 'stretch',
            pack: 'start'
        },
        autoScroll: true,
        disabled: true,
        border: 1,
        flex: 1,
        items: [
            this.regForm
        ]
    });

    this.tabContainer = Ext.create('Ext.tab.Panel', {
        scope: this,
        activeTab: 0,
        flex: 0.5,
        id: 'tabContainer',
        layout: { type: 'vbox', align: 'stretch' },
        plain: true,
        listeners: {
            tabchange: function (panel, newTab, oldTab) {
                Ext.getCmp('rightContainer').disable();
                FnClearValues();
                var getTabStat = this.getActiveTab();
                if (getTabStat.tabIndex == 0) {
                    Ext.getCmp('currentMonthsTree').store.load();
                }
                else if (getTabStat.tabIndex == 1) {
                    Ext.getCmp('allRecordsTree').store.load();
                }
            }
        },
        items: [
            this.currentMonthsTree, this.allRecordsTree
        ]
    });

    this.mainContainer = Ext.create('Ext.container.Container', {
        scope: this,
        bodyPadding: 10,
        title: 'MAIN',
        layout: {
            type: 'hbox',
            align: 'stretch'
        },
        flex: 1,
        items: [
            this.tabContainer,
            { xtype: 'splitter', width: 5, animate: true },
            this.rightContainer
        ]
    });

    this.add(this.mainContainer);
},
loadingOn: function () {
    setTimeout(function () { Ext.getCmp('currentMonthsTree').setLoading(true, true); }, 100);

},

loadingOff: function () {
    setTimeout(function () { Ext.getCmp('currentMonthsTree').setLoading(false, false); }, 100);


}
});
sra
  • 23,820
  • 7
  • 55
  • 89
EagleFox
  • 1,367
  • 10
  • 34
  • 58
  • Do your stores use remote paging or filtering? If they do not use either, I can tune this to be much faster. – Reimius Feb 01 '13 at 14:46
  • @Reimius ...much faster? I am eager to hear your approach. Cause we tested nearly any scenario for a real huge project where even micro optimizing was relevant. To only variant is to supply all data already with the application but that has it's own downsides. – sra Feb 01 '13 at 14:55
  • Actualy Reimius... I do not use paging or sorting at all, because the maximum records in each grid is 5. I'd definitely would like to see how u can tune this. – EagleFox Feb 01 '13 at 14:58

2 Answers2

3

You cannot do much more here. I think you can do some micro tunes but I doubt they are worth time they took to identify. If your app do the following you've done it all the right way;

  • Time till your is loaded
  • Init only the required controller and the stores (check each request)
  • Show the main view

As soon as your grids get rendered they will fire the load operation, at least when they have a paging toolbar. You could begin the load operation earlier, meaning before you create the view that may give you some milliseconds but I doubt that you can save more time.

This is of course based on the available information's.

sra
  • 23,820
  • 7
  • 55
  • 89
  • Agreed, there's really not much more to be done. I've noticed that ArrayStore tends to be faster than using pure JSON data, but that's still a micro-optimization. – Eric Feb 01 '13 at 14:46
  • I think i have done all that sra. my grids load only when the form is active... so when I click a tab to activate my form, it lags for about 3 seconds... I even made a stored procedure to return the values faster, but no improvements – EagleFox Feb 01 '13 at 15:00
  • @EagleFox That does not sound like a load problem... Note that a grid will render even if the store is not loaded. It will then simply show the loading message with a blurred body. So I guess you have a design/layout issue here which causes that. – sra Feb 01 '13 at 15:10
  • sra... on my firebug I can see all the four stores loading... please see my updated post – EagleFox Feb 01 '13 at 15:23
  • @EagleFox I see, but that should not stop your grids from being viewed. Something seems to block till the store(s) finish loading... reimius answer will definitiv help you speed it up a bit but there will be still something that blocks until the store finished loading. I think you will need to find this. – sra Feb 01 '13 at 15:29
  • Oh yeah... does sound like a layout issue. You may need to provide more of the layout part of your code so we can optimize that too. – Reimius Feb 01 '13 at 15:42
  • 2
    Also... Make sure to test the page without firebug open too. Firebug can really slow firefox down with Extjs sometimes because of the depth of the extjs code base. Use chrome if you want the speed to be 'normal' during debugging. – Reimius Feb 01 '13 at 15:44
  • @EagleFox I totally agree with reimius, you really should use chrome – sra Feb 01 '13 at 16:16
  • first of all Reimus and Sra... I'd really like to thank for both your time and effort... :)... please see my update... that is how I have laidout my application – EagleFox Feb 01 '13 at 16:34
  • @EagleFox That is quite a bit to much code ;) But I looked trough it and can say that you've have made several common errors where biggest is to create instances within a class-definition. That must not be done in most of the cases! Stay with only configurations when defining a class, not instances. Therefore I strictly recommend you to read [this SO answer](http://stackoverflow.com/a/14535598/701988) as well as [this SO answer](http://stackoverflow.com/a/14492347/701988). I know that this may not be what you want to hear but it will save you much pain in future. – sra Feb 01 '13 at 19:50
  • @EagleFox In addition [this articles](http://skirtlesden.com/articles/config-objects-on-the-prototype) describes the changes from 3.x to 4.x and may be worth reading too. – sra Feb 01 '13 at 19:51
  • thank you sra... anything that will help me improve... btw... I am totally not looking for a quick fix... so please don't hesitate to offer me any kind of advice... – EagleFox Feb 01 '13 at 20:03
3

Please reference my SO question that is very similar: Combo box loads too slow

Basically, you will want to define all your models as you do normally.

Then you will want to define all the stores for your page as array stores without proxies, like this:

var myStore1 = Ext.create("Ext.data.ArrayStore", {
    model: "MyModel1",
    data:  []
});

var myStore2 = Ext.create("Ext.data.ArrayStore", {
    model: "MyModel1",
    data:  []
});

Then you will want to create a single call to wherever you are getting your data from, you will need to change the server to output all the arrays into an single JSON object, something like this, and for super optimization, make them array arrays, this would be the output I would expect from the server:

{
     grid_data_1: [...],
     grid_data_2: [...]
}

Then on your webpage after you create all the stores, make a single ajax call to get the data for all four grids:

Ext.Ajax.request({
    url: 'url',
    method: 'GET',
    params: {
        ...whatever you want
    },

    success: function (response, opts) {
         var result = Ext.decode(response.responseText);
         myStore1.loadData(result.grid_data_1);
         myStore2.loadData(result.grid_data_2);
         ...
    },

});

This will make it much more efficient, you probably don't need to use array arrays in your case because there is only 5 rows per grid, but optimizing 4 ajax calls into one should have a large impact.

Community
  • 1
  • 1
Reimius
  • 5,694
  • 5
  • 24
  • 42
  • @EagleFox Correct, with that approach you reduce the request to just one. +1 I use direct since it was introduced to ExtJS and don't have those problems any more. But based on the last comment from eagle I think his problems depend on some layout issue. – sra Feb 01 '13 at 15:17
  • I think so too sra.. please see my update... can you see anything wrong on my layout... I think if I can figure out, it might be the FnSetValue... should I set my values for my forms and call the ajax on itemclick rather than 'selection change' – EagleFox Feb 01 '13 at 16:35
  • Thanks Reimius... it was indeed my layout... instead of calling a function 'onchange', I redirected it to itemclick event... and also implemented one ajax call on all 4 grid... significant improvement... thanks @sra for the heads up... u guys are awesome – EagleFox Feb 05 '13 at 16:42