Results 1 to 5 of 5

Thread: grid addRows performance

  1. #1
    Sencha User
    Join Date
    Mar 2007
    Location
    Boulder, CO
    Posts
    69

    Default grid addRows performance

    The dm.addRows call for 364 rows * 15 cols takes longer than I want the user to wait (9 seconds on my browser).

    What is the right approach to speed this up?

    I do not need a LoadableDataModel as all my data is already available.
    I just want the grid to draw a page and then draw other pages on demand but
    as I peruse the code it seems that the DefaultDataModel does not support paging.

    I assume I want to write a DataModel based on DefaultDataModel and then add paging?

    I'd appreciate if you could point me in the right direction.
    Thank you,
    Eric

  2. #2
    Ext User
    Join Date
    Mar 2007
    Posts
    48

    Default

    The bottleneck for me was the column resizing support. Do you need resiziable columns? I think Jack is working on a speedup that turns that off.

  3. #3
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    New York, NY
    Posts
    6,956

    Default

    If the user has sorted and you are using in-browser sorting that can slow it down too since it will sort the incoming data.

    For local data you could try this, but it's a hack and it won't maintain sorting:

    dataModel.data = yourNewData;
    dataModel.fireTableDataChanged();

    As for paging, that would really speed up the rendering if you could do it in paged blocks. You could extend DefaultDataModel and add the required methods (there's only a few defined in LoadableDataModel) to support paging from the local array. If you get this working I'd love a copy to include with the library if you are willing to share. If you have any problems implementing it, I'd be happy to answer any questions.

  4. #4
    Sencha User
    Join Date
    Mar 2007
    Location
    Boulder, CO
    Posts
    69

    Default

    Well, here's an attempt. When I enter a page number in the toolbar, it goes to the correct page.
    (I see no effect when I click the Toolbar buttons though, I imagine that's an unrelated problem.)

    I added a data member called "allData" to hold all rows, and a member function called setAllRows to set it as well as the totalCount data member.
    But would having dm.data hold all rows and adding a dm.pagedData makes more sense?
    Then the inherited DefaultDataModel functions will still operate on all the data.
    I imagine then that PagedDataModel.getValueAt would take the pageNum into account.
    Should I give that a try instead?

    (P.S. I've decided against paging and am going to try the other speedups mentioned but I'm willing to keep hacking here as well)

    Code:
    /*
     * YUI Extensions
     * Copyright(c) 2006, Jack Slocum.
     * 
     * This code is licensed under BSD license. 
     * http://www.opensource.org/licenses/bsd-license.php
     */
    
    /**
     * @class
     * This class extends DefaultDataModel and adds the core functionality to load data remotely. 
    
    
     * @extends YAHOO.ext.grid.DefaultDataModel
     * @constructor
     * @param {String} dataType YAHOO.ext.grid.PagedDataModel.XML, YAHOO.ext.grid.PagedDataModel.TEXT or YAHOO.ext.grid.JSON
    */
    YAHOO.ext.grid.PagedDataModel = function(data){
        YAHOO.ext.grid.PagedDataModel.superclass.constructor.call(this, []);
    	this.allData = data;
        
        /** Fires when a successful load is completed - fireDirect sig: (this)
         * @type YAHOO.util.CustomEvent 
         * @deprecated Use addListener instead of accessing directly
         */
        this.onLoad = new YAHOO.util.CustomEvent('load');
        /** Fires when a load fails - fireDirect sig: (this, errorMsg, responseObj)
         * @type YAHOO.util.CustomEvent 
         * @deprecated Use addListener instead of accessing directly
         */
        this.onLoadException = new YAHOO.util.CustomEvent('loadException');
        
        this.events['load'] = this.onLoad;
        this.events['beforeload'] = new YAHOO.util.CustomEvent('beforeload');
        this.events['loadexception'] = this.onLoadException;
        
        // paging info
        /** The active page @type Number*/
        this.loadedPage = 1;
        /** True to use remote sorting, initPaging automatically sets this to true @type Boolean */
        this.remoteSort = false;
        /** The number of records per page @type Number*/
        this.pageSize = 0;
        /** An object of key/value pairs to be passed as parameters
         * when loading pages/sorting @type Object*/
        this.baseParams = {};
        /** Maps named params to url parameters - Override to specify your own param names */
        this.paramMap = {'page':'page', 'pageSize':'pageSize', 'sortColumn':'sortColumn', 'sortDir':'sortDir'};
        
    };
    YAHOO.extendX(YAHOO.ext.grid.PagedDataModel, YAHOO.ext.grid.DefaultDataModel);
    
    /** @ignore */
    YAHOO.ext.grid.PagedDataModel.prototype.setLoadedPage = function(pageNum, userCallback){
        this.loadedPage = pageNum;
        if(typeof userCallback == 'function'){
            userCallback();
        }
    };
    
    /** Returns true if this model uses paging @type Boolean */
    YAHOO.ext.grid.PagedDataModel.prototype.isPaged = function(){
        return this.pageSize > 0;
    };
    
    /** Returns the total number of records available, override if needed @type Number */
    YAHOO.ext.grid.PagedDataModel.prototype.getTotalRowCount = function(){
        return this.totalCount || this.getRowCount();
    };
    
    /** Returns the number of records per page @type Number */
    YAHOO.ext.grid.PagedDataModel.prototype.getPageSize = function(){
        return this.pageSize;
    };
    
    /** Returns the total number of pages available @type Number */
    YAHOO.ext.grid.PagedDataModel.prototype.getTotalPages = function(){
        if(this.getPageSize() == 0 || this.getTotalRowCount() == 0){
            return 1;
        }
        return Math.ceil(this.getTotalRowCount()/this.getPageSize());
    };
    
    /** Initializes paging for this model. */
    YAHOO.ext.grid.PagedDataModel.prototype.initPaging = function(pageSize, baseParams){
        this.pageSize = pageSize;
        this.remoteSort = false;
        if(baseParams) this.baseParams = baseParams;
    };
    
    /** @ignore */
    YAHOO.ext.grid.PagedDataModel.prototype.createParams = function(pageNum, sortColumn, sortDir){
        var params = {}, map = this.paramMap;
        for(var key in this.baseParams){
            if(typeof this.baseParams[key] != 'function'){
                params[key] = this.baseParams[key];
            }
        }
        params[map['page']] = pageNum;
        params[map['pageSize']] = this.getPageSize();
        params[map['sortColumn']] = (typeof sortColumn == 'undefined' ? '' : sortColumn);
        params[map['sortDir']] = sortDir || '';
        return params;
    };
    
    YAHOO.ext.grid.PagedDataModel.prototype.loadPage = function(pageNum, callback, keepExisting){
        var sort = this.getSortState();
        var params = this.createParams(pageNum, sort.column, sort.direction);
        this.load(this.pageUrl, params, this.setLoadedPage.createDelegate(this, [pageNum, callback]), 
                   keepExisting ? (pageNum-1) * this.pageSize : null);
    };
    
    /** @ignore */
    YAHOO.ext.grid.PagedDataModel.prototype.applySort = function(suppressEvent){
    	if(!this.remoteSort){
            YAHOO.ext.grid.PagedDataModel.superclass.applySort.apply(this, arguments);
        }else if(!suppressEvent){
            var sort = this.getSortState();
            if(sort.column){
               this.fireRowsSorted(sort.column, sort.direction, true);
            }
        }
    };
    
    /** @ignore */
    YAHOO.ext.grid.PagedDataModel.prototype.resetPaging = function(){
    	this.loadedPage = 1;
    };
    
    /** Overridden sort method to use remote sorting if turned on */
    YAHOO.ext.grid.PagedDataModel.prototype.sort = function(columnModel, columnIndex, direction, suppressEvent){
        if(!this.remoteSort){
            YAHOO.ext.grid.PagedDataModel.superclass.sort.apply(this, arguments);
        }else{
            this.columnModel = columnModel;
            this.sortColumn = columnIndex;
            this.sortDir = direction;
            var params = this.createParams(this.loadedPage, columnIndex, direction);
            this.load(this.pageUrl, params, this.fireRowsSorted.createDelegate(this, [columnIndex, direction, true]));
        }
    }
    /**
     * Initiates the loading of the data from the specified URL - Failed load attempts will 
     * fire the {@link #onLoadException} event.
     * @param {Object/String} url The url from which the data can be loaded
     * @param {String/Object} params (optional) The parameters to pass as either a url encoded string "param1=1&param2=2" or as an object {param1: 1, param2: 2}
     * @param {Function} callback (optional) Callback when load is complete - called with signature (this, rowCountLoaded)
     * @param {Number} insertIndex (optional) if present, loaded data is inserted at the specified index instead of overwriting existing data
     */
    YAHOO.ext.grid.PagedDataModel.prototype.load = function(url, params, callback, insertIndex){
    	this.fireEvent('beforeload');
       var keepExisting = (typeof insertIndex == 'number');
    	try{
    		var pageNum = params[this.paramMap['page']];
    		this.loadedPage = pageNum;
    		var pageSize = this.getPageSize();
    		var first = (pageNum - 1) * pageSize;
    		var pageRows = this.allData.slice(first, first + pageSize);
    		if(keepExisting !== true){
    			this.removeAll();
    		}
    		this.addRows(pageRows);
        	if(typeof callback == 'function'){
    	    	callback(this, true);
    	    }
        	this.fireLoadEvent();
    	}catch(e){
    		this.fireLoadException(e, null);
    		if(typeof callback == 'function'){
    	    	callback(this, false);
    	    }
    	}
    };
    
    YAHOO.ext.grid.PagedDataModel.prototype.setAllRows = function(data){
    	this.allData = data;
    	this.totalCount = data.length;
    }
    
    /**@private*/
    YAHOO.ext.grid.PagedDataModel.prototype.processException = function(response){
        this.fireLoadException(null, response);
        if(typeof response.argument.callback == 'function'){
            response.argument.callback(this, false);
        }
    };
    
    YAHOO.ext.grid.PagedDataModel.prototype.fireLoadException = function(e, responseObj){
        this.onLoadException.fireDirect(this, e, responseObj);
    };
    
    YAHOO.ext.grid.PagedDataModel.prototype.fireLoadEvent = function(){
        this.fireEvent('load', this.loadedPage, this.getTotalPages());
    };

  5. #5
    Sencha User
    Join Date
    Mar 2007
    Location
    Boulder, CO
    Posts
    69

    Default

    Quote Originally Posted by devol
    The bottleneck for me was the column resizing support. Do you need resiziable columns? I think Jack is working on a speedup that turns that off.
    yep, resizable columns are a requirement.
    thanks.

Similar Threads

  1. Grid performance profile using Firebug
    By Animal in forum Ext 2.x: Help & Discussion
    Replies: 15
    Last Post: 27 Apr 2007, 10:30 AM
  2. Performance A2Rev5: Tab Switching with a tab being a Grid
    By Domitian in forum Ext 2.x: Help & Discussion
    Replies: 11
    Last Post: 8 Mar 2007, 7:52 AM
  3. dynamic grid column creation performance?
    By seno in forum Ext 1.x: Help & Discussion
    Replies: 1
    Last Post: 30 Nov 2006, 8:34 AM
  4. grid performance with many rows -- FastGridView
    By ericwaldheim in forum Community Discussion
    Replies: 7
    Last Post: 30 Oct 2006, 11:01 AM
  5. Grid & Slow performance?
    By [email protected] in forum Ext 1.x: Bugs
    Replies: 2
    Last Post: 24 Oct 2006, 9:35 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •