Results 1 to 2 of 2

Thread: How to increase the scrolling performance in a grid

  1. #1
    Sencha User
    Join Date
    Dec 2011
    Posts
    38

    Default How to increase the scrolling performance in a grid

    If in the configuration of the grid include rowexpander plugin, scrolling speed in Firefox 10.0.2 (Firebug 1.9.1) increases approximately in 2 times (for me).

    Ext version tested:
    • Ext 4.1 beta 1-3


    • Ext 4.1 rc1

    Browser:
    • Firefox 10.0.2


    • Firefox 11

    OS:
    • Windows 7


    How to check (an example).
    1.1.
    Set comment (see example program):
    //plugins: [{ ptype: 'rowexpander', width: 0, renderer: function () { return ''; }, rowBodyTpl: [''] }]
    1.2.
    Run example program.
    While pressing the button with the arrow down on the scrollbar, measure the time of scrolling up to 100 rows.

    2.1.
    Remove comment:
    plugins: [{ ptype: 'rowexpander', width: 0, renderer: function () { return ''; }, rowBodyTpl: [''] }]
    2.2.
    Run example program.
    While pressing the button with the arrow down on the scrollbar, measure the time of scrolling up to 100 rows.

    Result (Firefox 10.0.2, firefox 11.0):
    1 10-12 sec (without rowexpander plugin),
    2 6 sec (inserted rowexpander plugin).


    Example program.
    Code:
     Ext.Loader.setConfig({ enabled: true });
     Ext.Loader.setPath({ 'Ext': 'extjs', 'Ext.ux': 'ux' });
     Ext.require([
     	'Ext.grid.*',
     	'Ext.data.*',
     	'Ext.ux.RowExpander'
     ]);
     
     
     Ext.onReady(function ()
     {
     	var data = [];
     	for (var i = 1; i < 200; i++)
     	{
     		data.push({ 'id': i, 'name': 'Name ' + i, 'date': '2010/01/12','desc': 'A hsrild fjdow;s jriel '+ i + 'skdjfi dkldls dneiwr98' });
     	}
     
     	Ext.create('Ext.data.Store',
     	{
     		storeId: 'MyStore',
     		fields:
     		[
     			{ name: 'id', type: 'int' },
     			{ name: 'name', type: 'string' },
     			{ name: 'date', type: 'date' },
     			{ name: 'desc', type: 'string' }
     		],
     		data: data
     	});
     
     
     
     	Ext.define('MyGridWindow',
     	{
     		extend: 'Ext.window.Window', id: 'mygridwindow',
     		title: 'My grid Window',
     		width: 500, height: 220, x: 50, y: 108,
     		maximizable: true, closeAction: 'hide', layout: 'fit', collapsible: true, animCollapse: false,
     		shadow: true,
     		items:
     		{
     			xtype: 'grid', border: false, columnLines: true,
     			store: Ext.getStore('MyStore'),
     			columns:
     			[
     			{ text: 'No', xtype: 'rownumberer', width: 30 },
     			{ text: 'id', dataIndex: 'id', width: 70 },
     			{ text: 'Name', dataIndex: 'name', flex: 1 },
     			{ text: 'Date', dataIndex: 'date', width: 120, xtype: 'datecolumn' },
     			{ text: 'Desc', dataIndex: 'desc', flex: 1}
     			],
     			plugins: [{ ptype: 'rowexpander', width: 0, renderer: function () { return ''; }, rowBodyTpl: [''] }]
     		}
     	});
     
     
     	Ext.create('MyGridWindow');
     	Ext.getCmp('mygridwindow').show();
     
     
     });
    RowExpander file (the changes are highlighted in red):
    Code:
     Ext.define('Ext.ux.RowExpander', {
     	extend: 'Ext.AbstractPlugin',
      
     	requires: [
             'Ext.grid.feature.RowBody',
             'Ext.grid.feature.RowWrap'
         ],
      
     	alias: 'plugin.rowexpander',
      
     	width: 24,
      
     	rowBodyTpl: null,
      
     	/**
     	* @cfg {Boolean} expandOnEnter
     	* true to toggle selected row(s) between expanded/collapsed when the enter
     	* key is pressed (defaults to true).
     	*/
     	expandOnEnter: true,
      
     	/**
     	* @cfg {Boolean} expandOnDblClick
     	* true to toggle a row between expanded/collapsed when double clicked
     	* (defaults to true).
     	*/
     	expandOnDblClick: true,
      
     	/**
     	* @cfg {Boolean} selectRowOnExpand
     	* true to select a row when clicking on the expander icon
     	* (defaults to false).
     	*/
     	selectRowOnExpand: false,
      
     	rowBodyTrSelector: '.x-grid-rowbody-tr',
     	rowBodyHiddenCls: 'x-grid-row-body-hidden',
     	rowCollapsedCls: 'x-grid-row-collapsed',
      
      
      
     	renderer: function (value, metadata, record, rowIdx, colIdx)
     	{
     		metadata.tdCls = Ext.baseCSSPrefix + 'grid-cell-special';
     		return '<div class="' + Ext.baseCSSPrefix + 'grid-row-expander">&#160;</div>';
     	},
      
     	/**
     	* @event expandbody
     	*  element which owns the expanded row.
     	* @param {Ext.data.Model} record The record providing the data.
     	* @param {HTMLElement} expandRow The <tr> element containing the expanded data.
     	*/
      
     	constructor: function ()
     	{
     		this.callParent(arguments);
     		var grid = this.getCmp();
     		this.recordsExpanded = {};
     		// 
     		if (!this.rowBodyTpl)
     		{
     			Ext.Error.raise("The 'rowBodyTpl' config is required and is not defined.");
     		}
     		// 
     		// TODO: if XTemplate/Template receives a template as an arg, should
     		// just return it back!
     		var rowBodyTpl = Ext.create('Ext.XTemplate', this.rowBodyTpl),
                 features = [{
                 	ftype: 'rowbody',
                 	columnId: this.getHeaderId(),
                 	recordsExpanded: this.recordsExpanded,
                 	rowBodyHiddenCls: this.rowBodyHiddenCls,
                 	rowCollapsedCls: this.rowCollapsedCls,
                 	getAdditionalData: this.getRowBodyFeatureData,
                 	getRowBodyContents: function (data)
                 	{
                 		return rowBodyTpl.applyTemplate(data);
                 	}
                 }, {
                 	ftype: 'rowwrap'
                 }];
      
     		if (grid.features)
     		{
     			grid.features = features.concat(grid.features);
     		} else
     		{
     			grid.features = features;
     		}
      
     		// NOTE: features have to be added before init (before Table.initComponent)
     	},
      
     	init: function (grid)
     	{
     		this.callParent(arguments);
      
     		// Columns have to be added in init (after columns has been used to create the
     		// headerCt). Otherwise, shared column configs get corrupted, e.g., if put in the
     
     	// prototype.
     		grid.headerCt.insert(0, this.getHeaderConfig());
     		grid.on('render', this.bindView, this, { single: true });
     	},
      
     	getHeaderId: function ()
     	{
     		if (!this.headerId)
     		{
     			this.headerId = Ext.id();
     		}
     		return this.headerId;
     	},
      
     	getRowBodyFeatureData: function (data, idx, record, orig)
     	{
     		var o = Ext.grid.feature.RowBody.prototype.getAdditionalData.apply(this, arguments),
                 id = this.columnId;
     		o.rowBodyColspan = o.rowBodyColspan - 1;
     		o.rowBody = this.getRowBodyContents(data);
     		o.rowCls = this.recordsExpanded[record.internalId] ? '' : this.rowCollapsedCls;
     		o.rowBodyCls = this.recordsExpanded[record.internalId] ? '' : this.rowBodyHiddenCls;
     		o[id + '-tdAttr'] = ' valign="top" rowspan="2" ';
     		if (orig[id + '-tdAttr'])
     		{
     			o[id + '-tdAttr'] += orig[id + '-tdAttr'];
     		}
     		return o;
     	},
      
     	bindView: function ()
     	{
     		var view = this.getCmp().getView(),
                 viewEl;
      
     		if (!view.rendered)
     		{
     			view.on('render', this.bindView, this, { single: true });
     		} else
     		{
     			viewEl = view.getEl();
     			if (this.expandOnEnter)
     			{
     				this.keyNav = Ext.create('Ext.KeyNav', viewEl, {
     					'enter': this.onEnter,
     					scope: this
     				});
     			}
     			if (this.expandOnDblClick)
     			{
     				view.on('itemdblclick', this.onDblClick, this);
     			}
     			this.view = view;
     
     }
     	},
      
     	onEnter: function (e)
     	{
     		var view = this.view,
                 ds = view.store,
                 sm = view.getSelectionModel(),
                 sels = sm.getSelection(),
                 ln = sels.length,
                 i = 0,
                 rowIdx;
      
     		for (; i < ln; i++)
     		{
     			rowIdx = ds.indexOf(sels[i]);
     			this.toggleRow(rowIdx);
     		}
     	},
      
     	toggleRow: function (rowIdx)
     	{
     		var rowNode = this.view.getNode(rowIdx),
                 row = Ext.get(rowNode),
                 nextBd = Ext.get(row).down(this.rowBodyTrSelector),
                 record = this.view.getRecord(rowNode),
                 grid = this.getCmp();
      
     		if (row.hasCls(this.rowCollapsedCls))
     		{
     			row.removeCls(this.rowCollapsedCls);
     			nextBd.removeCls(this.rowBodyHiddenCls);
     			this.recordsExpanded[record.internalId] = true;
     			this.view.fireEvent('expandbody', rowNode, record, nextBd.dom);
     		} else
     		{
     			row.addCls(this.rowCollapsedCls);
     			nextBd.addCls(this.rowBodyHiddenCls);
     			this.recordsExpanded[record.internalId] = false;
     			this.view.fireEvent('collapsebody', rowNode, record, nextBd.dom);
     		}
     	},
      
     	onDblClick: function (view, cell, rowIdx, cellIndex, e)
     	{
      
     		this.toggleRow(rowIdx);
     	},
      
     	getHeaderConfig: function ()
     	{
     
     	var me = this,
                 toggleRow = Ext.Function.bind(me.toggleRow, me),
                 selectRowOnExpand = me.selectRowOnExpand;
      
     		return {
     			id: this.getHeaderId(),
     			width: me.width,
     			sortable: false,
     			resizable: false,
     			draggable: false,
     			hideable: false,
     			menuDisabled: true,
     			cls: Ext.baseCSSPrefix + 'grid-header-special',
     			renderer: me.renderer,
     			processEvent: function (type, view, cell, recordIndex, cellIndex, e)
     			{
     				if (type == "mousedown" && e.getTarget('.x-grid-row-expander'))
     				{
     					var row = e.getTarget('.x-grid-row');
     					toggleRow(row);
     					return selectRowOnExpand;
     				}
     			}
     		};
     	}
     });
    Well seen, if you do scrolling in the maximizing window.

  2. #2
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,379

    Default

    Having lots of rows is going to perform slower. If you are going to have a lot then I would suggest setting up buffer
    Mitchell Simoens @LikelyMitch

    Check out my GitHub:
    https://github.com/mitchellsimoens

    Posts are my own, not any current, past or future employer's.

Tags for this Thread

Posting Permissions

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