1. #1
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default [4.2.0 beta 2] a very simple/small remoter grid: performance compare to 3.4.x

    [4.2.0 beta 2] a very simple/small remoter grid: performance compare to 3.4.x


    I modified a sencha example remote grid (see attached files) to compare performance with 3.4.x. It is a very simple and small remote grid (6 columns and 27 rows data). I do following initial grid load measurements and tested with FF16 on same machine/same network.

    (1) Program start ( Ext.onReady) to grid render time.
    (2) Program start to grid view ready time.
    (3) Store before load to store load time.
    (4) Program start to store load time.

    All measured times with extjs4.2.0(beta2) and extjs 4.1.1a are at least 30%-50% slower than extjs 3.4.x. (#4 above item: .370 seconds vs .200 seconds ).

    Anyone has some kind of performance with extjs 4.1.x/4.2.x, or just me. Any methods to tune the performance to match 3.4.x? If this is a performance issue with extjs 4.1/4.2, I hope extjs 4.2.x release would at least pay an attention to improve the performance of simple grid.

    Most of my applications are similar to above remote grid, but with language translation, filter, column hide/show at initial load. They perform very well with extjs 3.4.x (less than .5 seconds with FF), but with extjs4.1.1a, users feel slowness (1-4 seconds with FF). Not sure how to use Ext.suspendLayouts() / Ext.resumeLayouts(), and/or store.suspendEvents() / store.resumeEvents() to improve performance for the grid initial load data.

    I am a Premium Member, but no sencha support answer my 4.1.1a question yet: http://www.sencha.com/forum/showthre...ch-extjs-3.4.x.

    4.2.0 test code: ( 3.4.x test code and remote data in zip file).
    PHP Code:
    Ext.onReady(function() {

        var 
    startTime = new Date().getTime();
        
    Ext.QuickTips.init();

        
    //Ext.suspendLayouts();
        
    Ext.define('Product', {
            
    extend'Ext.data.Model',
            
    fields: [{
                
    name'id',
                
    type'int'
            
    }, {
                
    name'company'
            
    }, {
                
    name'price',
                
    type'float'
            
    }, {
                
    name'date',
                
    type'date'
            
    }, {
                
    name'visible',
                
    type'boolean'
            
    }, {
                
    name'size'
            
    }]
        });

        var 
    beforeloadtime =''loadtime =''
        var 
    store Ext.create('Ext.data.JsonStore', {
            
    autoDestroytrue,
            
    model'Product',
            
    proxy: {
                
    type'ajax',
                
    url'grid-filter.json',
                
    reader: {
                    
    type'json',
                    
    root'data',
                    
    idProperty'id',
                    
    totalProperty'total'
                
    }
            },
            
    remoteSortfalse,
            
    sorters: [{
                
    property'company',
                
    direction'ASC'
            
    }],
        
    listeners: {    
            
    beforeload: {  
                
    fn: function() {
                    
    beforeloadtime = new Date().getTime();
                }
            },
            
    load: {  
                
    fn: function() {
                    
    loadtime = new Date().getTime();    
                    var 
    dt =  loadtime -  beforeloadtime;
                    var 
    dt2 =  loadtime startTime;
                    
    //store.resumeEvents()
                    
    console.info' extjs4.x total store load time (from store beforeload to load = 'dt);
                    
    console.info' extjs4.x total time (from start to store load = 'dt2);
                }
            },
            
    datachanged: {
                
    fn: function() {
                    var 
    headerCt grid.getComponent(0).headerCt,
                          
    headers headerCt.getGridColumns(),
                            
    index =  headerCt.items.findIndex('dataIndex''size'), 
                        
    myCol headers[index];
                    
    //myCol.setVisible( false ); 
                
    }

            }
        }
        });
      
        var 
    grid Ext.create('Ext.grid.Panel', {
            
    borderfalse,
            
    storestore,
            
    columns: {
                
    defaults: { sortabletrue }, 
            
    items: [{
                        
    dataIndex'id',
                        
    header'Id',
                
    flxe1,
                }, {
                        
    dataIndex'company',
                        
    header'Company',
                
    flxe1,
                        
    id'company'
                
    }, {
                        
    dataIndex'price',
                
    flxe1,
                        
    header'Price'
                
    }, {
                        
    dataIndex'size',
                
    flxe1,
                        
    header'Size'
                
    }, {
                        
    dataIndex'date',
                
    flxe1,
                
    header'Date',
                        
    rendererExt.util.Format.dateRenderer('m/d/Y')   
                }, {
                        
    dataIndex'visible',
                
    flxe1,
                        
    header'Visible'
                
    }]
        },
            
    loadMasktrue,
            
    dockedItems: [Ext.create('Ext.toolbar.Paging', {
                
    dock'bottom',
                
    storestore
            
    })],
            
    listeners: {
            
    afterlayout: {
                    
    fn: function(){         
               
    // console.info( '  afterlayout  =' );
                    
    }
                },
            
    viewready: {
                    
    fn: function(){
                var 
    endTime = new Date().getTime() - startTime;
                
    console.info'  extjs4.x total view ready time (from start to view ready )  = 'endTime);
                    }
                },
                
    render: {
                    
    fn: function(){
                var 
    endTime = new Date().getTime() - startTime;
                
    console.info'  extjs4.x total render time (from start to render ) = 'endTime);
               
    // store.suspendEvents();
                        
    store.load({
                            
    params: {
                                
    start0,
                                
    limit50
                            
    }
                        });
                    }
                }
            },
            
    emptyText'No Matching Records',
            
    title'Grid Filters Example',
            
    height400,
            
    width700,
            
    layout'fit',
        
    renderToExt.getBody(),
        });


    }); 
    Attached Files

  2. #2
    Sencha - Community Support Team mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    2,759
    Vote Rating
    108
    mankz is a name known to all mankz is a name known to all mankz is a name known to all mankz is a name known to all mankz is a name known to all mankz is a name known to all

      0  

    Default


    I'd guess it's related to the number of layout cycles performed (which reads a lot from the DOM, getStyle etc). Here's a short blog post I did on how to count those: http://www.bryntum.com/blog/improvin...a-performance/

  3. #3
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default


    Thanks. Will the patch apply to extjs 4.2 release? Then cannot wait to see the 4.2 release. (not sure how to use the patch - couldn't find 'AssertionGrid class' ).

    Yes, with attached simple test codes, you will see three times 'afterlayout' with 4.2, and twice with 3.4.

    Quote Originally Posted by mankz View Post
    I'd guess it's related to the number of layout cycles performed (which reads a lot from the DOM, getStyle etc). Here's a short blog post I did on how to count those: http://www.bryntum.com/blog/improvin...a-performance/

  4. #4
    Sencha - Community Support Team mankz's Avatar
    Join Date
    Nov 2007
    Location
    Stockholm, Sweden
    Posts
    2,759
    Vote Rating
    108
    mankz is a name known to all mankz is a name known to all mankz is a name known to all mankz is a name known to all mankz is a name known to all mankz is a name known to all

      0  

    Default


    Sorry, I wrote it a bit confusing - I don't work for Sencha. I just showed a simple way of measuring the nbr of layout cycles. You can try to measure this number in your test case to see how many layouts are performed.

  5. #5
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default


    Thanks.

    Hope sencha developers can find methods to reduce unnecessary layouts with extjs 4.2 release.

  6. #6
    Sencha User aw1zard2's Avatar
    Join Date
    Sep 2009
    Location
    Dallas, Texas
    Posts
    577
    Vote Rating
    32
    aw1zard2 has a spectacular aura about aw1zard2 has a spectacular aura about

      0  

    Default


    You should Define things outside of onReady.
    Moving from 3.4 to 4.2 we haven't seen any slowness but that is because we optimize the library to only what we need.

    Used JS Builder and now Sencha Command. Was getting 2.5k rows with 30 columns loading in about 1-2 seconds with 3.4 and 4.2 on IE8 WinXP SP3, so it just depends on how you have things structured and configured.

    We also have a Proof of Concept in which we made an Ext JS 3.4 grid display 10,000 rows in IE7 in 1 second. But we had to tweak how the rendering was working on that.
    The same page in Chrome showed all 10,000 rows in 0.5 seconds. FF was around 0.75 seconds for the 10,000 rows.

  7. #7
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default


    (1) That will be great, please help me if you can tweak this simple example with extjs 4.x.x to match extjs 3.4.x performance. Thank you.

    (2) If you are not working for Sencha, then Sencha support should do the same as you did to help me do the tweak. (I will create ticket for this).

    (3) My test examples are from extjs examples, there are almost exact same for both extjs 4.2.x and 3.4.x with simplification and easy comparisons (apple and apple compare).

    (4) I am not looking for grid display 10,000 rows data, but 25 -30 rows. Please keep mind large data always easy to optimization, and it also could hide some of real problems.

    (5) Please see attached page analyzer for initial grid load. Compare with ext3.4, there is extra grid layout (4.2.x did 3 grid layouts, 3.4.x did 2 grid layouts). For 4.2.x, last grid layout is from store.load->loadRecords->refresh->refreshSize->grid.updateLayout(). Don't understand why 'loadRecords' needs to do grid updateLayout. That is one of the reason that 4.2.x performance is about at least 30% slower than 3.4.x. Don't you think this is a bug?

    (6) Make thing worse, if there are hide/show columns during the initial load, then will trig another do layout.

    (7) For the best optimization, the grid initial load should only do grid layout once. It means that from grid start to initial store (records) loaded, it should only have one layout count. There are lots of room to improve grid performance to match 3.4.x.

    (8) So the goal will be internally (auto) and/or provide a method to reduce the do layout count to only one time when initial load remote grid data.



    Quote Originally Posted by aw1zard2 View Post
    You should Define things outside of onReady.
    Moving from 3.4 to 4.2 we haven't seen any slowness but that is because we optimize the library to only what we need.

    Used JS Builder and now Sencha Command. Was getting 2.5k rows with 30 columns loading in about 1-2 seconds with 3.4 and 4.2 on IE8 WinXP SP3, so it just depends on how you have things structured and configured.

    We also have a Proof of Concept in which we made an Ext JS 3.4 grid display 10,000 rows in IE7 in 1 second. But we had to tweak how the rendering was working on that.
    The same page in Chrome showed all 10,000 rows in 0.5 seconds. FF was around 0.75 seconds for the 10,000 rows.
    Attached Images

  8. #8
    Sencha User aw1zard2's Avatar
    Join Date
    Sep 2009
    Location
    Dallas, Texas
    Posts
    577
    Vote Rating
    32
    aw1zard2 has a spectacular aura about aw1zard2 has a spectacular aura about

      1  

    Default


    I will try to make time this weekend to update the example. I'm rather swamped right now but if you define everything first into a namespace then do 1 create in the onReady that should save you sometime.

    But removing everything from loading or doing dynamic loading of things required will cause a little lag but get the same results as creating 1 js file with everything in it.

    I don't work for Sencha but I do work at a corporation that handles millions of transactions during a 9-5 business day with Ext JS front end and Java back end. So the timing for us is very critical to be real time data.

    Just think of loading everything in the Ext JS library is like buying car with everything on it but if you live in Texas your never going to use the seat warmers in the car. In Texas you wouldn't buy a car with seat warmers cause its not needed. So why load everything for a simple grid if your never going to use tabpanels, trees, and etc.

  9. #9
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default


    Thank you. I have created a ticket with this for Sencha and hope they will figure it out. Here I just ask a very simple test example, and I do use namespace/class, etc in my application.

  10. #10
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default


    I turn out that the support ticket could not help me at all. I have to dig into extjs code and found out one bug on onProxyLoad function in Ext.data.Store.

    The following is patch which will match extjs 3.4.x total layouts (twice) for initial grid load, it also will prevent all layouts with column hide/show during the initial grid load. This patch will dramatically improve performance if there are column hide/show during the initial grid data load.

    However, the overall performance is still slower (at least 25%) than 3.4.x. I hope Sencha will make effort to match 3.4.x performance.

    PHP Code:

    Ext
    .define('My.patch.data.Store', {     override'Ext.data.Store',
        
    onProxyLoad: function(operation) { 
            var 
    me this,
                
    resultSet operation.getResultSet(),
                
    records operation.getRecords(),
                
    successful operation.wasSuccessful();

            if (
    resultSet) {
                
    me.totalCount resultSet.total;
            }

            
    Ext.suspendLayouts(); // added code
            
    if (successful) {
                
    me.loadRecords(recordsoperation); // this will trig layout
            
    }
            
    me.loading false;
            if (
    me.hasListeners.load) { 
                
    me.fireEvent('load'merecordssuccessful); // this will trig layout
            
    }
            if (
    me.hasListeners.read) {
                
    me.fireEvent('read'merecordssuccessful);
            }
            
    Ext.resumeLayouts(true); // added code
            
            
    Ext.callback(operation.callbackoperation.scope || me, [recordsoperationsuccessful]);
        }
    });