PDA

View Full Version : Deferred destroy



jclawson
24 Jul 2009, 1:40 PM
A particular page in an interface I have written contains a good amount of components. Enough so that if you navigate away from this interface, and the container is destroyed you can get a slow script warning on some machines. The destroy operation can take a lot of time and locks up the browser while its running.

Do you think it would be a good idea to make destroy operations deferred (in a setTimeout) so that other operations may execute in between this thread of execution?

I did a quick test... and I was pleased with the result:



Ext.override(Ext.Container, {
beforeDestroy : function(){
if(this.items){
Ext.each(this.items, function(item){
if(item) {
if(item instanceof Ext.Container) {
item.destroy.defer(1,item);
} else {
item.destroy();
}
}
});
}
if(this.monitorResize){
Ext.EventManager.removeResizeListener(this.doLayout, this);
}
Ext.destroy(this.layout);
Ext.Container.superclass.beforeDestroy.call(this);
}
});


*This is not a fix at all and this should not be used in any production app.*

I created a page with several containers containing multiple htmleditors to test (48 editors to be exact). I also added a progress bar and let it wait() with animation to give an indication of browser javascript responsiveness.

Then, I destroyed the panel. Without the patch the browser would lock up and progress animation would freeze. Buttons on the page would not show hover state and were not clickable. With the patch applied I didn't notice any interruption in user activity. The progress animation continued smoothly.

What do you think of this? Do you think this is something you would consider implementing in a future release? This will require some more significant code changes so that you are able to determine when precisely a component was finished being destroyed. (perhaps a callback on destroy/beforeDestroy/onDestroy)

evant
24 Jul 2009, 3:35 PM
I think the idea itself is interesting, if you do happen to be cleaning up a large number of components. If you're doing it as a big cleanup and you're sure nothing new will be created in the meantime, it's a good approach. At this point though I don't see it going into the base library until the idea is fleshed out a lot more.

jclawson
27 Jul 2009, 9:01 AM
There is an error in my code (I have been testing many different methods to accomplish this). Here is a better test case; simpler too. It distributes the work done randomly over 5 seconds. Again, this is not a fix. I am unsure if this will cause memory leaks... For instance if the parent gets destroyed prior to its children--- can this cause leakage? I think some work needs to be done on the performance of Ext. Perhaps deferred grid row/column rendering (like what flex does), smarter component resizing (resizing a page with lots of components can hang the browser), deferred destroy (who really cares if the destroy takes 5 seconds if the UI doesn't lag at all?), switching to a tab with lots of components hangs the browser even when the tab has been rendered.




var destroyOriginal = Ext.Component.prototype.destroy;
Ext.override(Ext.Component, {
destroy : function(){
destroyOriginal.defer((Math.random()*5000), this, arguments);
}
});