PDA

View Full Version : [CLOSED][3.0.0] Ext.Panel.onResize triggers two resize events



Niels Brouwers
30 Jul 2009, 3:15 AM
Hello,

I'm developing an ExtJS 3.0 application which has a rather heavy UI. The usability of the app is fine, although resizing the browser window resulted in extremely slow performance.

It turns out that there's an issue with Ext.Panel.onResize, where calling the function with two numbers will cause the function to first call setWidth() and then setHeight(), generating two resize events instead of one. Unless I'm mistaken the correct behavior should be that if onResize is called with two numbers, it should call setSize(), generating only a single resize event. This causes components to be resized more often than needed, greatly degrading performance for my application.

To illustrate my point, here's a patch that fixes the problem for me.


// keep the old implementation as a back-up
Ext.Panel.prototype.oldResize = Ext.Panel.prototype.onResize;

// replace the onResize method
Ext.Panel.prototype.onResize = function(w, h)
{

// if both the width and height are numbers
if (typeof w == 'number' && typeof h == 'number' && !this.collapsed)
{
this.body.setSize(
this.adjustBodyWidth(w - this.getFrameWidth()),
this.adjustBodyHeight(h - this.getFrameHeight())
);

} else
// fall back on the old implementation
this.oldResize(w, h);

};

Animal
30 Jul 2009, 4:15 AM
Resizing the browser window being slow:

Set Ext.Container.prototype.bufferResize = false; at the top of your app before the onReady call.

Niels Brouwers
30 Jul 2009, 4:25 AM
Yes I was already using that, but thanks for the tip.

I noticed that the resizing is particularly slow on Firefox (3.0.11, 3.5.1, even with tracemonkey enabled) but fine on Opera 9.64, IE 6, 7, 9, and Safari 4.0. I guess it's just another Firefox problem.

But the Ext.Panel.onResize() bug still stands of course.

Niels Brouwers
30 Jul 2009, 5:12 AM
Here's a formal bug report :)

Ext version tested:

Ext 3.0.0


Adapter used:

ext


css used:

only default ext-all.css




Browser versions tested against:

Opera 9.64
IE6
IE8
FF3.0.11
FF3.5.1 (tracemonkey off)
FF3.5.1 (tracemonkey on)
Safari 4


Operating System:

Ubuntu Linux 8.10
XP Pro SP3
Vista
OSX


Description:

There's an issue with Ext.Panel.onResize, where calling the function with two numbers will cause the function to first call setWidth() and then setHeight(), generating two resize events instead of one.


Steps to reproduce the problem:

Create a viewport with a panel, and another panel inside that: viewport(panel(panel)).
Attach a resize event handler to the inner panel
Watch two events getting fired as you resize the browser window.


The result that was expected:

Resizing an Ext.Panel should fire only a single resize event, not two.


The result that occurs instead:

Two resize events are fired, one when the height of the panel is adjusted, another when the width is adjusted.


Debugging already done:

Ext.Panel.onResize(w, h) calls setWidth(w) and setHeight(h) when both w and h are numbers. Since both setWidth() and setHeight() automatically fire resize events, resizing an Ext.Panel causes two such events to be fired instead of one.




onResize : function(w, h){
if(w !== undefined || h !== undefined){
if(!this.collapsed){

// check if w is a number, and call setWidth if so
if(typeof w == 'number'){
this.body.setWidth(
this.adjustBodyWidth(w - this.getFrameWidth()));
}else if(w == 'auto'){
this.body.setWidth(w);
}

// check if w is a number, and call setHeight if so
if(typeof h == 'number'){
this.body.setHeight(
this.adjustBodyHeight(h - this.getFrameHeight()));
}else if(h == 'auto'){
this.body.setHeight(h);
}

// at this point, if both w and h are numbers, setWidth and setHeight have fired resize
// events

if(this.disabled && this.el._mask){
this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
}
}else{
this.queuedBodySize = {width: w, height: h};
if(!this.queuedExpand && this.allowQueuedExpand !== false){
this.queuedExpand = true;
this.on('expand', function(){
delete this.queuedExpand;
this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
this.doLayout();
}, this, {single:true});
}
}
this.fireEvent('bodyresize', this, w, h);
}
this.syncShadow();
}


Possible fix:

Check if both w and h are numbers and call setSize(w, h)


Workaround:


// keep the old implementation as a back-up
Ext.Panel.prototype.oldResize = Ext.Panel.prototype.onResize;

// replace the onResize method
Ext.Panel.prototype.onResize = function(w, h)
{

// if both the width and height are numbers
if (typeof w == 'number' && typeof h == 'number' && !this.collapsed)
{
this.body.setSize(
this.adjustBodyWidth(w - this.getFrameWidth()),
this.adjustBodyHeight(h - this.getFrameHeight())
);

} else
// fall back on the old implementation
this.oldResize(w, h);

};

evant
30 Jul 2009, 5:34 AM
Thanks for the report, we'll check it out.

evant
30 Jul 2009, 8:31 PM
To clarify:



var i = 0;
Ext.onReady(function(){
new Ext.Viewport({
layout: 'fit',
items: {
layout: 'fit',
items: {
title: 'a',
listeners: {
resize: function(){
console.log(++i);
}
}
}
}
});
});


When I resize the window it only shows the counter being incremented one at a time. Please post a test case.

Niels Brouwers
31 Jul 2009, 12:23 AM
Hmm, it seems I made a wrong assumption that setWidth and setHeight on the body triggered resize events. As it turns out this.body is actually a DOM Element and not an Ext.Component at all.

What I observed was that resizing a panel with a heavy grid in it on Firefox takes about ~1-2 seconds on my machine (core duo 1.66ghz, 2gb ram, also observed on other similar machines with different OS/FF version combinations). The odd thing is that you can see it resize horizontally and vertically in two steps. I can provide a screengrab of this behavior if so desired. This made me think that Ext was issuing two resize events rather than one. A lot of debugging code later and I thought I tracked down the problem. I guess I was wrong :/

So even if Ext is not firing two resize events, Gecko is still extremely slow resizing, and seems to do the resize in two steps rather than one.

The suggested optimisation does alleviate the problem. You can probably close this ticket.

evant
31 Jul 2009, 12:33 AM
We are looking into the issue re: bufferResize, for the time being use the override.