Zac
12 Jun 2007, 5:25 PM
6/14 - Completely rewrote this thread because the old version was too complicated to show the issue easily.
Ext leaks DOM elements in IE. This has a big effect on performance after multiple widgets are created and destroyed.
Steps to Reproduce:
Download sIEve @ http://home.orange.nl/jsrosman/
Take the Hello World dialog example and add in a new button in the .html.
Hook a click event up to that button in the .js and use it to call dialog.destroy(true) (Code below to make it quicker.)
Load the document in sIEve.
Click the 'Hello World' button. Memory and # of DOM nodes will increase.
Click the button you created. Notice changes to memory and # of nodes.
Click on the 'Show In Use' button and look for Yes in the Orphan column.
In the Hello World example above it removes 19 of the 68 DOM nodes created correctly. Most of the leftovers are orphans that IE can't remove because they are still referenced somewhere in the JS and vice-versa.
This is a problem with desktop-style applications that are expected to run all day without crashing. There's no way I'd be comfortable convincing my boss to let me use Ext for a project knowing this would be a big problem down the road.
You can blame IE for this...but realize that almost all of the big companies are locked into using it.
hello.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Hello World Dialog Example</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<!-- GC --> <!-- LIBS -->
<script type="text/javascript" src="../../adapter/yui/yui-utilities.js"></script>
<script type="text/javascript" src="../../adapter/yui/ext-yui-adapter.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all.js"></script>
<script language="javascript" src="hello.js"></script>
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../examples.css" />
</head>
<body>
<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->
<h1>Hello World Dialog</h1>
<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>
<input type="button" id="show-dialog-btn" value="Hello World" /><br /><br />
<input type="button" id="close-dialog-btn" value="Goodbye World" /><br /><br />
<p>Note that the js is not minified so it is readable. See <a href="hello.js">hellos.js</a> for the full source code.</p>
Here's snapshot of the code that creates the dialog:
<pre class="code"><code>dialog = new Ext.BasicDialog("hello-dlg", {
modal:true,
autoTabs:true,
width:500,
height:300,
shadow:true,
minWidth:300,
minHeight:300
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog).disable();
</code></pre>
<!-- The dialog is created from existing markup.
The inline styles just hide it until it created and should be in a stylesheet -->
<div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">
<div class="x-dlg-hd">Hello Dialog</div>
<div class="x-dlg-bd">
<!-- Auto create tab 1 -->
<div class="x-dlg-tab" title="Hello World 1">
<!-- Nested "inner-tab" to safely add padding -->
<div class="inner-tab">
Hello...<br><br><br>
</div>
</div>
<!-- Auto create tab 2 -->
<div class="x-dlg-tab" title="Hello World 2">
<div class="inner-tab">
... World!
</div>
</div>
</div>
</div>
</div>
</body>
</html>
hello.js
/*
* Ext JS Library 1.1 Beta 1
* Copyright(c) 2006-2007, Ext JS, LLC.
* licensing@extjs.com
*
* http://www.extjs.com/license
*/
// create the HelloWorld application (single instance)
var HelloWorld = function(){
// everything in this space is private and only accessible in the HelloWorld block
// define some private variables
var dialog, showBtn, hideBtn;
// return a public interface
return {
init : function(){
showBtn = Ext.get('show-dialog-btn');
// attach to click event
showBtn.on('click', this.showDialog, this);
hideBtn = Ext.get('close-dialog-btn');
hideBtn.on('click', this.closeDialog, this);
},
showDialog : function(){
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new Ext.BasicDialog("hello-dlg", {
autoTabs:true,
width:500,
height:300,
shadow:true,
minWidth:300,
minHeight:250,
proxyDrag: true
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog).disable();
dialog.addButton('Close', dialog.hide, dialog);
}
dialog.show(showBtn.dom);
},
closeDialog : function(dlg) {
dialog.destroy(true);
delete dialog;
}
};
}();
// using onDocumentReady instead of window.onload initializes the application
// when the DOM is ready, without waiting for images and other resources to load
Ext.onReady(HelloWorld.init, HelloWorld, true);
Ext leaks DOM elements in IE. This has a big effect on performance after multiple widgets are created and destroyed.
Steps to Reproduce:
Download sIEve @ http://home.orange.nl/jsrosman/
Take the Hello World dialog example and add in a new button in the .html.
Hook a click event up to that button in the .js and use it to call dialog.destroy(true) (Code below to make it quicker.)
Load the document in sIEve.
Click the 'Hello World' button. Memory and # of DOM nodes will increase.
Click the button you created. Notice changes to memory and # of nodes.
Click on the 'Show In Use' button and look for Yes in the Orphan column.
In the Hello World example above it removes 19 of the 68 DOM nodes created correctly. Most of the leftovers are orphans that IE can't remove because they are still referenced somewhere in the JS and vice-versa.
This is a problem with desktop-style applications that are expected to run all day without crashing. There's no way I'd be comfortable convincing my boss to let me use Ext for a project knowing this would be a big problem down the road.
You can blame IE for this...but realize that almost all of the big companies are locked into using it.
hello.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Hello World Dialog Example</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<!-- GC --> <!-- LIBS -->
<script type="text/javascript" src="../../adapter/yui/yui-utilities.js"></script>
<script type="text/javascript" src="../../adapter/yui/ext-yui-adapter.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all.js"></script>
<script language="javascript" src="hello.js"></script>
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../examples.css" />
</head>
<body>
<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->
<h1>Hello World Dialog</h1>
<p>This example shows how to create a very simple modal BasicDialog with "autoTabs".</p>
<input type="button" id="show-dialog-btn" value="Hello World" /><br /><br />
<input type="button" id="close-dialog-btn" value="Goodbye World" /><br /><br />
<p>Note that the js is not minified so it is readable. See <a href="hello.js">hellos.js</a> for the full source code.</p>
Here's snapshot of the code that creates the dialog:
<pre class="code"><code>dialog = new Ext.BasicDialog("hello-dlg", {
modal:true,
autoTabs:true,
width:500,
height:300,
shadow:true,
minWidth:300,
minHeight:300
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog).disable();
</code></pre>
<!-- The dialog is created from existing markup.
The inline styles just hide it until it created and should be in a stylesheet -->
<div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">
<div class="x-dlg-hd">Hello Dialog</div>
<div class="x-dlg-bd">
<!-- Auto create tab 1 -->
<div class="x-dlg-tab" title="Hello World 1">
<!-- Nested "inner-tab" to safely add padding -->
<div class="inner-tab">
Hello...<br><br><br>
</div>
</div>
<!-- Auto create tab 2 -->
<div class="x-dlg-tab" title="Hello World 2">
<div class="inner-tab">
... World!
</div>
</div>
</div>
</div>
</div>
</body>
</html>
hello.js
/*
* Ext JS Library 1.1 Beta 1
* Copyright(c) 2006-2007, Ext JS, LLC.
* licensing@extjs.com
*
* http://www.extjs.com/license
*/
// create the HelloWorld application (single instance)
var HelloWorld = function(){
// everything in this space is private and only accessible in the HelloWorld block
// define some private variables
var dialog, showBtn, hideBtn;
// return a public interface
return {
init : function(){
showBtn = Ext.get('show-dialog-btn');
// attach to click event
showBtn.on('click', this.showDialog, this);
hideBtn = Ext.get('close-dialog-btn');
hideBtn.on('click', this.closeDialog, this);
},
showDialog : function(){
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new Ext.BasicDialog("hello-dlg", {
autoTabs:true,
width:500,
height:300,
shadow:true,
minWidth:300,
minHeight:250,
proxyDrag: true
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog).disable();
dialog.addButton('Close', dialog.hide, dialog);
}
dialog.show(showBtn.dom);
},
closeDialog : function(dlg) {
dialog.destroy(true);
delete dialog;
}
};
}();
// using onDocumentReady instead of window.onload initializes the application
// when the DOM is ready, without waiting for images and other resources to load
Ext.onReady(HelloWorld.init, HelloWorld, true);