PDA

View Full Version : Improving column.show() and hide() performance(ie8 unresponsive script)?



wilfogn
8 Mar 2016, 11:54 AM
I am upgrading an application with a 30 column grid with grouping, pagination, and filtersFeature and need to show/hide 6 of these columns based on a selected options. I have to support ie8 and this operation is causing ie8 unresponsive scripts. I have implemented suspendLayout() and resumeLayout() which improved the speed of this operation from 2800 ms to 1500ms. Are there any more improvements I can make to get thing to work on ie8? Thank you.



var time1 = new Date().getTime();
Ext.suspendLayouts();
if (select == '1') {
Ext.getCmp('a').hide();
Ext.getCmp('b').hide();
Ext.getCmp('c').show();
Ext.getCmp('d').show();
Ext.getCmp('e').show();
Ext.getCmp('f').show();
} else {
Ext.getCmp('a').show();
Ext.getCmp('b').show();
Ext.getCmp('c').hide();
Ext.getCmp('d').hide();
Ext.getCmp('e').hide();
Ext.getCmp('f').hide();
}
Ext.resumeLayouts(true);
var time2 = new Date().getTime();
console.log(time2 - time1 + ' ms');

jdkhamba
8 Mar 2016, 5:10 PM
Instead of show/hide after the grid has been created, you already know which columns need to be hidden based on your business logic. So why not create the columns config array with hidden:true or false first and then create the grid with the dynamic column config? That should speed things up.

In other word something like this :


var columns = []
if(..)
columns = [{text:'col1',hidden:true},{text:'col2',hidden:false}];
else
columns = [{text:'col1',hidden:false},{text:'col2',hidden:true}];

var yourGrid = Ext.widget('grid',{columns:columns};

wilfogn
9 Mar 2016, 10:00 AM
Good thought, unfortunately my users will be switching between business logic options after the grid/store has been loaded. Though you got me thinking about grid.reconfigure which might work if I can find a way to maintain my filters through swaps.

My main head scratch is why a single column.hide is taking 250ms.

jdkhamba
9 Mar 2016, 12:37 PM
Well looks like column.hide() does quite a bit looking at the source code :


hide: function(fromOwner) {
var me = this,
ownerHeaderCt = me.getOwnerHeaderCt(),
owner = me.ownerCt,
ownerIsGroup,
item, items, len, i;

// If we have no ownerHeaderCt, it's during object construction, so
// just set the hidden flag and jump out
if (!ownerHeaderCt) {
me.callParent();
return me;
}


// Save our last shown width so we can gain space when shown back into fully flexed HeaderContainer.
// If we are, say, flex: 1 and all others are fixed width, then removing will do a layout which will
// convert all widths to flexes which will mean this flex value is too small.
if (ownerHeaderCt.forceFit) {
me.visibleSiblingCount = ownerHeaderCt.getVisibleGridColumns().length - 1;
if (me.flex) {
me.savedWidth = me.getWidth();
delete me.flex;
}
}

ownerIsGroup = owner.isGroupHeader;


// owner is a group, hide call didn't come from the owner
if (ownerIsGroup && !fromOwner) {
items = owner.query('>:not([hidden])');
// The owner only has one item that isn't hidden and it's me; hide the owner.
if (items.length === 1 && items[0] == me) {
me.ownerCt.hide();
return;
}
}


Ext.suspendLayouts();


if (me.isGroupHeader) {
items = me.items.items;
for (i = 0, len = items.length; i < len; i++) {
item = items[i];
if (!item.hidden) {
item.hide(true);
}
}
}


me.callParent();
// Notify owning HeaderContainer
ownerHeaderCt.onHeaderHide(me);


Ext.resumeLayouts(true);
return me;
},


If the number of possibilities are limited how about have one base class grid definition with all the common features like filter etc and create inherited classes based on the business logic and created the ones needed. Then once all the grids are created, they can be a part of a container with card layout and you can activate the correct one based on the user selection.In that case you would simple show hide the right grid instead of messing with the columns.

wilfogn
16 Mar 2016, 12:18 PM
In the end I found a simple solution: setSize to 0
I also found that doing a "store.removeAll()" before performing this operation also improved performance significantly.



//params change
store.removeAll();
Ext.getCmp('column_a').setSize({width: 0, height: 20});
store.reload(with new params);


Thank you.