PDA

View Full Version : A question about memory usage



garyng
2 Apr 2007, 3:15 AM
Hi,

ext-all.js has a size of about 500K. While it can be gzipped to 110K on the wire(and cached) it would still be expanded to 500K. So if I have multiple pages opened, would it be multiplied ?

This may not be a problem on modern machines but would it be a problem on memory constrained thin client, especially when FF is already notorious of using lots of memory.

jay@moduscreate.com
2 Apr 2007, 5:00 PM
Hi,

ext-all.js has a size of about 500K. While it can be gzipped to 110K on the wire(and cached) it would still be expanded to 500K. So if I have multiple pages opened, would it be multiplied ?

This may not be a problem on modern machines but would it be a problem on memory constrained thin client, especially when FF is already notorious of using lots of memory.



Hi garyng,
if the pages (including iframes) call extjs explicitly, yes. this is effective for anything the web pages load. If you open 3 tabs, with a site, your memory usage will go up. Even though the disk cache may not change much, your RAM will be utilized for each page loaded.

ericwaldheim
6 Apr 2007, 8:02 AM
And if I have ten tabs I have a lot of code loaded. The profiler in my head asks if there's a way around it. I tried out "var Ext = parent.Ext;" in a tab's iframe but the problem of course is that the parent's Ext operates on the parent's window, parent's dom, parent's document.
I'm curious, is it possible (theoretically) to have a parent.Ext manipulate another iframe's window/document/dom? In the meantime I suppose it's time to learn to use a real profiler and perhaps see if using divs instead of iframes in my tabs is a workable alternative.

Any insight appreciated.
Thanks,
Eric

Joe
6 Apr 2007, 11:59 AM
I will throw this out for discussion.

I do not use iframes - we can load a page into a content panel. This loaded page can access not only all of Ext but the main object defined in the calling page, allowing for object to object communication - very powerful.

The loaded pages can create grids, load trees, everything the main page can do - but with no reference to .js at all. This makes the pages load really fast and should also reduce memory usage by not loading up Ext each time.

That said, this is not nearly as easy as it sounds, here are considerations I had to work out to make it work. Once these considerations were taken care of (encapulated into a design framework) this approach has proved to make for really fast loading pages that can communicate with all other loaded pages, then do data only pulls and transfer data between pages that were all loaded after the fact.

The design of Ext is true genius to make this available.

Considerations:
1) Pages can not have the same div id since Ext caches. Because 'pages' have div tag id's 'hard coded' on them generally - you have to dynamically create all div tags referenced in your code (i.e. to use as the element to create a grid in). The other option is to strip/replace the ids to make them unique. I strip out and replace div ids needed on init to get around this.
2) The document referenced is actually the one from the main page, so you can not submit forms in the normal way. I just post the form in the background, which works out nice - you can catch a failure without ever losing the entered data on the form.
3) Styles are loaded globally on the page. Seems like if you just do not use the same style name for two different definitions you are fine. This is not my strong point, maybe many style sheet considerations I am not aware of but have not hit any issues in that respect. In fact being able to access the same set of style references from pages loaded after the fact is once again proving to provide power and functionality.

Ext is the best thing since sliced bread .. or whatever was before that.

I am very interested in comment.

Joe
6 Apr 2007, 1:32 PM
I realized after posting the above comment that it was just a bunch of air with no code.

The following two standard html files show how this works.

First you have the mom.htm file. It has all the references to ext.
Next you have the kid.htm. It has no reference to ext.

The mom file loads up the kid file (and turns on script).

The kid file loads and talks to mom.

Mom talks back and the child responds as expected.

This shows how once loaded, a page with no Ext reference can access the loading object as well as all Ext functions.

As you can see kid.htm can call Ext.MessageBox.alert with no reference to the .js files and kid can talk to mom and vice versa. Multiple kids can be loaded, all with the object name kid with no problem. However if any of those kid.htm files were to have divs with ids like 'tree-view' then you run into issues that can be resolved (see previous post).

mom.htm


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>mom</title><script type="text/javascript" src="/yui-ext/yui-utilities.js"></script><script type="text/javascript" src="/yui-ext/ext-yui-adapter.js"></script><script type="text/javascript" src="/yui-ext/ext-all.js"></script><link rel="stylesheet" type="text/css" href="/yui-ext/resources/css/ext-all.css" />
<script language="JavaScript" type="text/javascript">
//----Main Form
var mom = function(){
return {
hi : function(o){
o.hi(mom);
},
momSays : function(answer){
mom.ismad = (answer != 'no');
Ext.get("play-area").load({
url: '/kid.htm',
scripts:true, /*very important*/
text: "Loading child object ..."
});
},
init : function(){
var umad = Ext.MessageBox.confirm('Confirm', 'Are you mad?', this.momSays)
}
};
}();

//=== Entry Point
Ext.EventManager.onDocumentReady(mom.init, mom, true);
</script>
</head>
<body>
<h1>Mom</h1>
<div id='play-area'></div>
</body>
</html>



kid.htm



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script language="JavaScript" type="text/javascript">

var kid = function(){
return {
hi : function(o){
if (o.ismad === false){
Ext.MessageBox.alert(kid.childname + ' says', 'Hi Mom!');
} else {
Ext.MessageBox.alert('Answering service says', 'Bubba is away right now.');
}
},
init : function(){
this.childname = 'Bubba';
mom.hi(this);
}
};
}();

Ext.EventManager.onDocumentReady(kid.init, kid, true);
</script>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<b>Bubba was here</b>
</body>
</html>


I realize there is a logic error in the code. If Bubba just said hi to mom, how could he then be gone? He left - it's just a demo :)

Hope this help or at least spawns discussion.

cdomigan
6 Apr 2007, 10:08 PM
Thanks Joe, you make some really good points. I have been thinking through these myself.

Just curious, in your last example aren't you ending up with "illegal" html code? You are loading an html page (html tags and all) into a div. I didn't think this was "permissible".

Cheers,

Chris

Joe
7 Apr 2007, 6:11 AM
Normally I do this into a Content panel (which I think is usually in a div anyway). Normally I pull from a Notes server. I put this into html files to make it easier for people who want to recreate this to do so with no modification. That said, my server also spits out <HTML>.

I am using the "out of the box" functionality of pulling a page into a content panel. I have read nothing about issues pulling in a full page.

I do not get any error in either i.e. 6/7/or FF. If is this "technically" illegal or not - no sure.

I have not run into issues - even doing pretty complex stuff with this (nested layouts in previously loaded layout region - then load a grid .. do it again and remove them all. No errors.

I have read jack mention something along the lines of "technically matching standard" vs "actually working on all browsers". The later seems most important.

Comments?

NoDice
7 Apr 2007, 11:30 AM
Hey Joe,
I would definitely agree that b (actually working in all browsers) is most important, but at the same time cdomigan does seem to be correct in that it is not permissible to load
<html> tags inside other
<html> tags and from your example it does not seem to be necessary. When "MOM" loads play-area via an Ajax request, the request just has to return



<div> buba was here </div>
<script>

//your kid javascript here

</script


This way you return less data and the resulting html would still be valid and you do not need to load multiple EXT/.js files.

For discussions, i have been in the practice of loading all javascript at once and using callbacks to initiate it when a panel is loaded. My reasoning is that it seems redundant to pull down the script every time a panel is loaded / reloaded. This way the js is already there and waiting and as soon as a panel is loaded (which is faster cause i am not waiting for the js to be downloaded and parsed ) the callback will start the js. How do others view this situation?

Animal
7 Apr 2007, 1:06 PM
I agree with Joe, and handle my app in a very similar way.

I have a singleton object which does all the Layout initialization, and exposes methods which loaded ContentPanels may use.

It might be true that full HTML pages should not be inserted as innerHTML (which is how dynamic content is loaded), but I know of no standards covering that (innerHTML is a nonstandard extension, introduced I think by Microsoft which has become a de facto standard, a bit like the XML HttpRequest), and it seems to work by simply discarding the "illegal" elements.

I have chosen to correct this in my application though.

All my JSP pages use a <myapp:Page> tag around the whole page which, if NOT called by an Ajax request wraps the page with the proper DOCTYPE, and <html><head><body> tags. If it is being called by an Ajax request, it does no wrapping, and just the page's content is served.

Joe
7 Apr 2007, 4:50 PM
Hey Joe,
I... i have been in the practice of loading all javascript at once and using callbacks to initiate it when a panel is loaded. My reasoning is that it seems redundant to pull down the script every time a panel is loaded / reloaded.

I agree and that is how I do it as well. I am not pulling Ext JS each time. Other than the few characters for the "wire frame" of the object definition, there is little redundant code. Of course I can not put 20 pages of super complex code out here to make a point, so I put out 2 simple HTML files that can be easily run and modified. The point of the 2 objects - which seem redundant - is show how you can load an object, without redundantly pulling Ext JS and then have that object be "smart" and communicate with other objects previously loaded.

If I do not need a smart object, I simply use the method you discuss to pull an display data (i.e. JsonView to div).

So this is not here as the only way to program a page, but only as yet another option.

A summary of discussion:
1) Using iframes does not allow "attachment" to already loaded extjs in memory or other objects
2) Using ajax calls to pull objects in allows for the same Ext JS base to be used (in memory) and object communication
3) Do not pull the same object logic over and over, if you have common logic, put it in the main page or load into memory as needed (not redundantly over and over).
4) If your page contains HTML start and end tags, to be 'up to standard', you should either 1) strip these out if you have no control over the source or 2) not include them in the first place if you have control.

Did I miss any important points .. other important points?


Thanks to all for discussion - and Animal - that is a very smart way to handle that HTML tags standards issue, thanks for sharing. Learning every day.

dalsbury
9 Apr 2007, 7:20 AM
Joe or anyone for that matter,
When I use the same basic structure as Joe did in his example I find that I end up with an error, though my code still accomplishes the desired results minus the error message. The error that I receive is "Ext is not defined" because the Javascript is for some reason executed twice. The first time "Ext" is not defined, and the second time "Ext" is defined.

This is the code that loads the child module:


Ext.get("mainPanel").load({
url: panelURL + panelURLParameters,
scripts: true,
text: "Loading ..."
});


If the scripts is set to false, the page still executes once, but "Ext" is still not defined. On the second pass with scripts set to true, "Ext" is defined.

The workaround that I found though it seems a kludge is the following:


<script language="JavaScript" type="text/javascript">
var myForm = function(){
var simple = new Ext.Form({
labelWidth: 75, // label settings here cascade unless overridden
url:'save-form.php'
});
simple.add(
new Ext.form.TextField({
fieldLabel: 'Email',
name: 'email',
vtype:'email',
width:175
})
);
simple.render('form-ct');
};
// This is where I prevent the error by only executing on the second pass once Ext is defined
if (typeof(window['Ext']) !== "undefined")
{
Ext.onReady(myForm);
}
</script>


This seems to stop the errors, but I am wondering if there is a way to prevent the first execution of the code.

Joe
9 Apr 2007, 7:45 AM
If you load the same page up two times with the same div-id or div-id that matches anything already loaded (i.e. tool-bar-area), you will get errors. The reason your second one worked may have been due to a change of the div id from mainPanel to form-ct. If mainPanel was already being used as a div tag id - then the div id may be what did the fix, not the restructure. I am interested to know if you load the same page twice - as shown above - if you still get errors or see UI problems (i.e. both objects using same div).

Below code is from this post:
http://extjs.com/forum/showthread.php?t=3534&page=2#15

I always have issues if this is the case - and use this getID() function to strip out duplicates. However I think using the DomHelper as described by Animal to dynamically build the content with unique ids may be the preferred method.



toID : function(o){
//- Finds an id, converts it to a unique id and returns new id
//- used to double load the same page
if(o.label == null){return ''};
var area = Ext.get( o.label );
var newid = Ext.id();
area.dom.id = newid;
return newid;
}

dalsbury
10 Apr 2007, 9:00 AM
My problem is solved. It was a stupid mistake. Making the transition from iframes to Joe's sample, I left my hidden iframe in my HTML, but I removed it from the BorderLayout, so it was no longer visible.

To make Joe's example work for me, I added a click handler to my menu tree, but I did not realize that the href (which I forgot to remove) in my tree would still fire pointing to the hidden iframe. The iframe would load the href first, throw an error, then the click handler would load the same page in the BorderLayout which would load without an error. Because the iframe did not load Ext libraries, the error "Ext is not defined" would occur.

Thanks for the help

genius551v
10 Apr 2007, 12:13 PM
very very much interesting this discussion, i follow this to close, please continue explain the metodo, tnks =D>

genius551v
10 Apr 2007, 1:16 PM
ok, i have this...

my "MOM" pag:


<html>
<head>
<title>Mom</title>
<link href="web/css/jack2/loading.css" type="text/css" rel="stylesheet">
</head>

<body scroll="no">
<div id="loading">
<div class="loading_body"><div class="loading_indicator">Loading...</div></div>
</div>

<link rel="stylesheet" type="text/css" href="web/css/jack2/ext-all.css">
<link rel="stylesheet" type="text/css" href="web/css/jack2/styles.css">

<script type="text/javascript" src="web/js/jack2/yui-utilities.js"></script>
<script type="text/javascript" src="web/js/jack2/ext-yui-adapter.js"></script>
<script type="text/javascript" src="web/js/jack2/ext-all-debug.js"></script>

<script type="text/javascript" src="web/js/view/main-apiviewer.js"></script>

<div id="northPanel" class="x-layout-inactive-content">
<img id="logo" src="web/images/aplication/logos/logo.png">
<div id="titleHeader">my title</div>
</div>

<div id="westPanel" class="x-layout-inactive-content">
<div id="main_menutree"></div>
</div>

<div id="eastPanel" class="x-layout-inactive-content"></div>

<div id="centerPanel" class="x-layout-inactive-content">
<!--<iframe id="centerIframe" src="index.php?action=CmdDefaultInicio" frameBorder="0"></iframe>--> NOW I DONT USE
</div>

<div id="southPanel" class="x-layout-inactive-content"></div>
</body>
</html>


and my "KID" page:


<html>
<head>
<title>Kid</title>
</head>

<body scroll="no">
<script language="JavaScript" src="web/js/grids2/grid-editor.js"></script>

//THIS IS JUST A SMARTY PLUGIN
{select_estado_to_grid name="sel_estado" style="display: none;" table_name="estado" label="nombre" value="id"}

{hidden_idsesion name="idsesion"} //THIS IS OTHER SMARTY PLUGIN

<div id="grid-panel">
<div id="grid-editor"></div>
</div>
</body>
</html>


Ok, my Main_ApiViewer.js is:


Main_ApiViewer = function() {
var layout;

return {
init : function() {
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

Ext.QuickTips.init();

layout = new Ext.BorderLayout(document.body, {
hideOnLayout: true,
north: {
initialSize: 84
},
west: {
split: true,
initialSize: 200,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true,
showPin: true,
margins: {top:3,left:3,right:-3,bottom:3},
cmargins: {top:3,left:3,right:0,bottom:3}
},
east: {
split: true,
initialSize: 200,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true,
showPin: true,
margins: {top:3,left:-3,right:3,bottom:3},
cmargins: {top:3,left:0,right:3,bottom:3}
},
center: {
titlebar: true,
margins: {top:3,left:3,right:3,bottom:3}
},
south: {
split: true,
initialSize: 100,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true,
showPin: true,
collapsedTitle: 'South Panel',
margins: {top:-3,left:3,right:3,bottom:3},
cmargins: {top:0,left:3,right:3,bottom:1}
}
});

layout.beginUpdate();

layout.add('north', new Ext.ContentPanel('northPanel',{id:'north', title:'North Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('west', new Ext.ContentPanel('westPanel',{id:'west', title:'West Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('east', new Ext.ContentPanel('eastPanel',{id:'east', title:'East Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('center', new Ext.ContentPanel('centerPanel',{id:'center', title:'Center Panel', fitToFrame:true, autoScroll:true, closable:false}));
layout.add('south', new Ext.ContentPanel('southPanel',{id:'south', title:'South Panel', fitToFrame:true, autoScroll:true, closable:true}));

layout.restoreState();

Main_MenuTree.init();

layout.endUpdate();

Ext.get('loading').remove();
},

//THIS IS THE FUNCTION TO LOAD WHIT A IFRAME BUT HERE IN THIS EXAMPLE DO NOT USED
loadPag : function(iframe,url){
Ext.get(iframe).dom.src = url;
},

//THIS IS THE FUNCTION TO USED
loadWhitOutIframe: function(url) {
Ext.get('centerPanel').load({
url: url,
scripts: true,
text: "Loading..."
});
}
};
}();
Ext.onReady(Main_ApiViewer.init, Main_ApiViewer, true);


the tree jus do it:


tree.on('click', function(node) {
if(!node.isExpanded())
node.reload(); //THIS IS OK
if(node.attributes.url && node.attributes.url!='')
//Main_ApiViewer.loadPag('centerIframe',node.attributes.url); //THIS IS TO IFRAME AND WORKS FINE
Main_ApiViewer.loadWhitOutIframe(node.attributes.url); //NOW USED THIS
});


and just dont load...:((

note:
my url is "url"=>"index.php?action=BPCmdDefaultKidPage" this is about my framework but whit iframe i dont have problems

what is wrong?

Tnks for your help....

Joe
10 Apr 2007, 4:10 PM
It may be that you are getting the element in general not specifically the ContentPanel when using Ext.get.

Just a shot - try changing this....



//THIS IS THE FUNCTION TO USED
loadWhitOutIframe: function(url) {
Ext.get('centerPanel').load({
url: url,
scripts: true,
text: "Loading..."
});
}
};



to something like this ... I have not tested the code, but you get the idea.




//----- In your code after setting up your layout add this
this.layout = layout;

//----- Then update function as follows
//THIS IS THE FUNCTION TO USED
loadWhitOutIframe: function(url) {
this.layout.getRegion('center').getActivePanel().load({
url: url,
scripts: true,
text: "Loading..."
});
}
};


It looks like from your other code, the IFrame one was reloading in the same location, killing the old one. If that was the case, this should provide similar results.

Note: You may need to do some cleanup of the items on the existing content panel before removing / replacing it. I use a process where each object "registers" itself with Mom. Then a call tells the kid to unload, removing resources and in my case the related loaded Content Panel as well. This is important or you may end up with things like "hidden grids" that kick out errors when you resize, use memory, etc.

kitepad
10 Apr 2007, 7:29 PM
ok, i have this...

my "MOM" pag:


<html>
<head>
<title>Mom</title>
<link href="web/css/jack2/loading.css" type="text/css" rel="stylesheet">
</head>

<body scroll="no">
<div id="loading">
<div class="loading_body"><div class="loading_indicator">Loading...</div></div>
</div>

<link rel="stylesheet" type="text/css" href="web/css/jack2/ext-all.css">
<link rel="stylesheet" type="text/css" href="web/css/jack2/styles.css">

<script type="text/javascript" src="web/js/jack2/yui-utilities.js"></script>
<script type="text/javascript" src="web/js/jack2/ext-yui-adapter.js"></script>
<script type="text/javascript" src="web/js/jack2/ext-all-debug.js"></script>

<script type="text/javascript" src="web/js/view/main-apiviewer.js"></script>

<div id="northPanel" class="x-layout-inactive-content">
<img id="logo" src="web/images/aplication/logos/logo.png">
<div id="titleHeader">my title</div>
</div>

<div id="westPanel" class="x-layout-inactive-content">
<div id="main_menutree"></div>
</div>

<div id="eastPanel" class="x-layout-inactive-content"></div>

<div id="centerPanel" class="x-layout-inactive-content">
<!--<iframe id="centerIframe" src="index.php?action=CmdDefaultInicio" frameBorder="0"></iframe>--> NOW I DONT USE
</div>

<div id="southPanel" class="x-layout-inactive-content"></div>
</body>
</html>


and my "KID" page:


<html>
<head>
<title>Kid</title>
</head>

<body scroll="no">
<script language="JavaScript" src="web/js/grids2/grid-editor.js"></script>

//THIS IS JUST A SMARTY PLUGIN
{select_estado_to_grid name="sel_estado" style="display: none;" table_name="estado" label="nombre" value="id"}

{hidden_idsesion name="idsesion"} //THIS IS OTHER SMARTY PLUGIN

<div id="grid-panel">
<div id="grid-editor"></div>
</div>
</body>
</html>


Ok, my Main_ApiViewer.js is:


Main_ApiViewer = function() {
var layout;

return {
init : function() {
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

Ext.QuickTips.init();

layout = new Ext.BorderLayout(document.body, {
hideOnLayout: true,
north: {
initialSize: 84
},
west: {
split: true,
initialSize: 200,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true,
showPin: true,
margins: {top:3,left:3,right:-3,bottom:3},
cmargins: {top:3,left:3,right:0,bottom:3}
},
east: {
split: true,
initialSize: 200,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true,
showPin: true,
margins: {top:3,left:-3,right:3,bottom:3},
cmargins: {top:3,left:0,right:3,bottom:3}
},
center: {
titlebar: true,
margins: {top:3,left:3,right:3,bottom:3}
},
south: {
split: true,
initialSize: 100,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true,
showPin: true,
collapsedTitle: 'South Panel',
margins: {top:-3,left:3,right:3,bottom:3},
cmargins: {top:0,left:3,right:3,bottom:1}
}
});

layout.beginUpdate();

layout.add('north', new Ext.ContentPanel('northPanel',{id:'north', title:'North Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('west', new Ext.ContentPanel('westPanel',{id:'west', title:'West Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('east', new Ext.ContentPanel('eastPanel',{id:'east', title:'East Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('center', new Ext.ContentPanel('centerPanel',{id:'center', title:'Center Panel', fitToFrame:true, autoScroll:true, closable:false}));
layout.add('south', new Ext.ContentPanel('southPanel',{id:'south', title:'South Panel', fitToFrame:true, autoScroll:true, closable:true}));

layout.restoreState();

Main_MenuTree.init();

layout.endUpdate();

Ext.get('loading').remove();
},

//THIS IS THE FUNCTION TO LOAD WHIT A IFRAME BUT HERE IN THIS EXAMPLE DO NOT USED
loadPag : function(iframe,url){
Ext.get(iframe).dom.src = url;
},

//THIS IS THE FUNCTION TO USED
loadWhitOutIframe: function(url) {
Ext.get('centerPanel').load({
url: url,
scripts: true,
text: "Loading..."
});
}
};
}();
Ext.onReady(Main_ApiViewer.init, Main_ApiViewer, true);


the tree jus do it:


tree.on('click', function(node) {
if(!node.isExpanded())
node.reload(); //THIS IS OK
if(node.attributes.url && node.attributes.url!='')
//Main_ApiViewer.loadPag('centerIframe',node.attributes.url); //THIS IS TO IFRAME AND WORKS FINE
Main_ApiViewer.loadWhitOutIframe(node.attributes.url); //NOW USED THIS
});


and just dont load...:((

note:
my url is "url"=>"index.php?action=BPCmdDefaultKidPage" this is about my framework but whit iframe i dont have problems

what is wrong?

Tnks for your help....

Hi,

Would you share your sample with all source?

Very thanks.

Joe
11 Apr 2007, 4:20 AM
Did you add...
this.layout = layout after created in Init?

... and then update the one line ?
from: Ext.get('centerPanel').load
to: this.layout.getRegion('center').getActivePanel().load

And still did not work?

My code is also in a Lotus Notes database - merged with other stuff. It will do you little good as I do not do what you are doing in the above area.

Here is a shorthand version of what I do


//--- var cp = <get your content panel - not Element (do NOT use Ext.get('someid')>
var mgr = cp.getUpdateManager();
mgr.loadScripts = true;
mgr.on('update', function(){//do soemthing } );
var openurl = o.url + con.noCacheURL(); //update to your url
mgr.update(openurl , "" );

genius551v
11 Apr 2007, 7:30 AM
Hi joe and everybody,

tnks for you fast answer, this work:


loadWhitOutIframe: function(url){
var cp = layout.getRegion('center').getActivePanel();
var mgr = cp.getUpdateManager();
mgr.loadScripts = true;
mgr.on('update', function(){alert('Your content panel has been update!');} );
//var openurl = o.url + con.noCacheURL(); //update to your url
//o and con i dont have this but i like will have
//so until understand o and con i put my:
var openurl = url; //just url :D
mgr.update(openurl , "" );
}

and ready...great work and tnks very very much

ok, this work too but i think this is not to recommend?


loadPag : function(iframe, url){
Ext.get('centerPanel').load({ //I ACCES TO DIV DIRECTLY
url: url,
scripts: true,
text: "Loading..."
});
}


and now just for complement, can you share a example to destroy "the element" to update other and other and other the same way?

TNKS

note:
kitepad, soon upload the all source for you and everybody, just give me a moment

genius551v
11 Apr 2007, 2:15 PM
ok my code complete is

principal (MOM) html:


<html>
<head>
<title>Mom pag</title>
<link href="css/jack2/loading.css" type="text/css" rel="stylesheet">
</head>

<body scroll="no">
<div id="loading">
<div class="loading_body"><div class="loading_indicator">Loading...</div></div>
</div>

<link rel="stylesheet" type="text/css" href="css/jack2/ext-all.css">
<link rel="stylesheet" type="text/css" href="css/jack2/styles.css">

<script type="text/javascript" src="js/jack2/yui-utilities.js"></script>
<script type="text/javascript" src="js/jack2/ext-yui-adapter.js"></script>
<script type="text/javascript" src="js/jack2/ext-all-debug.js"></script>

<script type="text/javascript" src="js/view/mom.js"></script>

<div id="wPanel" class="x-layout-inactive-content">
<!--menu or someting-->
</div>

<div id="cPanel" class="x-layout-inactive-content" style="border: 1px solid red;">
<!--work area-->
</div>

</body>
</html>


mom.js:


Mom = function() {
var layout;

return {
init : function() {
layout = new Ext.BorderLayout(document.body, {
hideOnLayout: true,
west: {
split: true,
initialSize: 200,
minSize: 1,
maxSize: 400,
collapsible: true,
titlebar: true
},
center: {
titlebar: true
}
});

layout.beginUpdate();

layout.add('west', new Ext.ContentPanel('wPanel',{id:'west', title:'West Panel', fitToFrame:true, autoScroll:true, closable:true}));
layout.add('center', new Ext.ContentPanel('cPanel',{id:'center', title:'Center Panel', fitToFrame:true, autoScroll:false, closable:false}));

layout.restoreState();

layout.endUpdate();

Ext.get('loading').remove();
//USE YOUR HREF OR URL YOU WANT LOAD
this.loadPag('yourPath/Kid.html');
},

loadPag : function(url){
var cp = layout.getRegion('center').getActivePanel();
var mgr = cp.getUpdateManager();
mgr.loadScripts = true;
mgr.on('update', function(){alert('your panel has bee update!');});
var openurl = url;
mgr.update(openurl , "" );
}
};
}();
Ext.onReady(Mom.init, Mom, true);


second (KID) html:


<!--NOTE: can you see, dont invoque yui-utilities.js, ext-yui-adapter.js or ext-all-debug.js again -->

<script language="JavaScript" src="js/grids2/kid.js"></script>

<div id="grid-panel" style="border: 1px solid yellow;"> <!--pay attetion to this color!!!-->
<div id="grid-editor" style="border: 1px solid #000000;"></div> <!--and to this color!!!-->
</div>


kid.js


Kid = function(){
var cm;
var ds;
var sm;
var grid;

return {
init : function(){

var fm = Ext.form, Ed = Ext.grid.GridEditor;

var cols = [{
header: "Id",
dataIndex: 'col0',
width: 30,
editor: new Ed(new fm.NumberField({allowBlank: false}))
},{
header: "Name",
dataIndex: 'col1',
width: 200,
editor: new Ed(new fm.TextField({allowBlank: false}))
},{
header: "Date1",
dataIndex: 'col2',
width: 100,
editor: new Ed(new fm.TextField({allowBlank: false}))
},{
header: "Date2",
dataIndex: 'col3',
width: 100,
editor: new Ed(new fm.TextField({allowBlank: false}))
},{
header: "state",
dataIndex: 'col5',
width: 100,
editor: new Ed(new fm.TextField({allowBlank: false}))
},{
header: "Observ",
dataIndex: 'col4',
renderer: italic,
editor: new Ed(new fm.TextField({allowBlank: true}))
}];

cm = new Ext.grid.ColumnModel(cols);
cm.defaultSortable = true;

var recordDefinition = Ext.data.Record.create([
{name: 'col0', type: 'int'},
{name: 'col1', type: 'string'},
{name: 'col2', type: 'string'},
{name: 'col3', type: 'string'},
{name: 'col5', type: 'string'},
{name: 'col4', type: 'string'}
]);

ds = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({url: 'xml/dataSourceFile.xml'}),
reader: new Ext.data.XmlReader({record: 'tag'}, recordDefinition)
});

sm = new Ext.grid.RowSelectionModel();

grid = new Ext.grid.EditorGrid('grid-editor', {
ds: ds,
cm: cm,
selModel: sm
});

grid.render();

var layout_grid = Ext.BorderLayout.create({
center: {
margins:{left:0,top:0,right:0,bottom:0},
panels: [new Ext.GridPanel(grid)]
// OR (grid, {fitContainer:true, fitToFrame:true, resizeEl:'grid-editor'})] ANYWAY DONT WORK!!!
}
}, 'grid-panel');

var gridHead = grid.getView().getHeaderPanel(true);
var tb = new Ext.Toolbar(gridHead, [{
text: 'Add Plant',
handler : function(){
var p = new Plant({
common: 'New Plant 1',
light: 'Mostly Shade',
price: 0,
availDate: new Date(),
indoor: false
});
grid.stopEditing();
ds.insert(0, p);
grid.startEditing(0, 0);
}
}]);

ds.load();
}
};
}();
Ext.onReady(Kid.init, Kid, true);

ok this is all code

result: (view attachments)

but i dont understand why panel-grid dont resize if panel resize but windows resized yes resize, can see the colors in the image result, some body can help me whit that?

tnks

Joe
11 Apr 2007, 4:03 PM
I have been doing some testing and cleaning out the grid from memory is proving to be very tough.

Here was the process
Created a set of nested divs for the grid and ContentPanel
Loaded the grid with a ds (array) and cm - direct from the example.
Loaded the CP into the center LayoutRegion

First just to show an obvious memory trap, I just removed the div. This was to show an easy example of what 'cleanup' is and why you need it.

Next I used grid.destroy(); and removed CP from Region, used CP.destroy and removed all divs. But still something left in memory.

Next I tracked the ds and cm and purgeListeners them both and set cm, ds and grid to null.

Still memory grows as I add and remove these items.

I will try to create simple enough code to recreate, but there is more ....

The other thing I notice is that when loading in an iframe - when the iframe is reloaded, all that memory used is cleaned up - zip - just like that - no cleanup needed at all (just like when you reload the main page).

This makes me wonder if iframes are not better when loading these heavier widgets.

Door Number Three
You can share Ext from within in iframe.

In the top document - add this code;
window.Ext = Ext;

Then in the iframe loaded document add this line early.
var Ext = top.window.Ext;

You can use Ext functions - but not exactly as you would if they were loaded in a local Ext. Since you are sharing Ext with the main document - and Ext is very connected to document, you will see that Ext.get does not work - it tries to 'get' from the parent document in which it was contained in. There is a way to 'get' from the current document, just not using Ext.get(). Also because the 'document' (main doc) has already loaded, that blows the onReady - it kicks off before the page is built. So this is NOT how Ext was designed to be used - pout. Would be nice if the doc and window and small Ext shell could be created and then "attached" to an Ext core where the doc is passed in the background allowing for seamless separation and sharing - but that is getting way too deep.

So we have 3 doors:
1) Load page via Ajax or add controls to dynamically created divs / CPs. Memory is hard to keep clean but this does not double up Ext in memory like normal iframe usage does. Loaded page is "morphed" into main pages "space". Div ids clash, the document and window references are of the top page, etc. It has been assimilated.
2) Load via iframe with all references to Ext - making a local separate Ext available. Here you can access your own Ext / document and the parent (and other) Ext / documents - but adds to memory heavily when each page is open.
3) Load via iframe but connect to parent windows Ext. This saves memory and load time in that is sharing Ext but still has it's own document and own memory space that is 'cleaned up' by the browser. The downside being what will and will not work since Ext is so embedded with document and this was not the intended use of Ext - so this could be very bad.

All three have highs and lows - none are perfect.

If someone has code that shows how to add a grid in a new content panel, remove it and do this over and over with no added memory usage (like you can with iframe) - then please provide that. I am stumped.

Comments?

cdomigan
11 Apr 2007, 4:50 PM
Joe, I use option one. I also generate a unique id (uid) for each contentpanel. I then pass this uid as a parameter to my server, so that the fetched page "knows" it's context, and can generate completely unique id's for its elements. Then if I have to do any Ext.selects etc I just make sure it's looking under my uid+'_container' div as the context.

Wolfgang
12 Apr 2007, 12:19 AM
@Joe
For your "Door numer 3" (iframe), have you had a look at this thread?
http://extjs.com/forum/showthread.php?t=1201

It looks like what you figured out, and the question remains wether that attempt has also the issue of Ext and the document object with for example Ext.get() as you pointed out earlier.

Joe
12 Apr 2007, 4:57 AM
Thanks for the link, I had read that - but did not quite get it. Now that I understand better - I will try to implement that code and see how it effects things and post details here.

Thanks for reading, discussing and pointing me to more resources :)

Cheers

genius551v
12 Apr 2007, 6:11 AM
Hi,

cdomigan, can you share someone example that your talking about?


I use option one. I also generate a unique id (uid) for each contentpanel. I then pass this uid as a parameter to my server, so that the fetched page "knows" it's context, and can generate completely unique id's for its elements. Then if I have to do any Ext.selects etc I just make sure it's looking under my uid+'_container' div as the context.

Tnks

Joe
12 Apr 2007, 8:08 AM
I did something similar, where I created a CP with a unique id using - Ext.id(). Next that id is passed into URL that is loaded into the content panel.

(i.e. myurl = 'someserverproc?runit&name=bob&cpid=' + cpid )

Then in the server process, grab the id from query_string and can pass that back to the main parent object when saying hello (like the mom/kid example says hello, but passes the ID pulled from query_string).

That is a basic summary of the process as I know it / used it.

That said - I found adding the id to each call to be a bit if a pain - so I use another method of grabbing the id by running up the dom. If I can find time and anyone is interested - I can post a slimmed down version of how this works with momma and bubba :).

Here are some basics:

On top of the form I add a div with a common name such as:

<div id='con-sub-obj'></div>

Then use the function below (toID) like this: (con is the name of my 'mom' object). Stands for 'console'.


var newID = con.toID( { label: 'con-sub-obj' } );
This is to strip out the name and replace it with a unique ID to keep it from being there when the next page loads.

Next I get find the cp id using findCPID shown below:

var cpid = con.findCPID(newID);

This gets the cpid it was loaded into (as opposed to passing in the URL each time).



toID : function(o){
//- Finds an id, converts it to a unique id and returns new id
//- used to double load the same page
if(o.label == null){return ''};
var area = Ext.get( o.label );
var newid = Ext.id();
area.dom.id = newid;
return newid;
}




findCPID : function(o){
//--- Finds parent CPID for name passed and converts to unique id
// (as to not conflict with next one of same type loaded)
//--- Note: Can update as needed to find the CPID from object passed
var area = Ext.get(o);
var areadom = area.dom;
areadom = areadom.parentNode.parentNode;
area.dom.id = Ext.id();
return areadom.id
},



Note: This is 'early' code - I would do a bit different now - but still posting it.

Hope this helps :)

genius551v
17 Apr 2007, 5:48 AM
people interesting in memory, checkout this:http://extjs.com/forum/showpost.php?p=23143&postcount=21

Belgabor
17 Apr 2007, 8:46 AM
people interesting in memory, checkout this:http://extjs.com/forum/showpost.php?p=23143&postcount=21

I don't think this saves memory, it just reduces load time. Things are imported from the mom page, but have to be injected into the child, where they take up the same amount of memory as if they were loaded normally.

Jamie Avins
17 Apr 2007, 12:17 PM
Don't forget the magic of DomQuery when using many dynamic id's. I rarely use a straight get by id's anymore as most everything I use in this type of application is generated on the fly.

genius551v
17 Apr 2007, 12:41 PM
Belgabor, JCA...look like you two knew much of the subject, can you share for all please, examples or something.

tnks

Joe
18 Apr 2007, 10:41 AM
I finally got my head around the injection model and it does seems it would reduce load time but non memory usage since you are still duplicating and even evaluating the same code.

In my mind the major code base should be written in a way that allows it to "hang" off the window and be reused by all sub loaded frames. I have been able to simulate this using jQuery by referencing parent.jQuery in iframe loaded pages.

Example
you can use: parent.jQuery('#dupID', document) to use the jQuery already existing on the parent window to look in the currently loaded document. You can use parent.jQuery('#dupID') and this pulls the same div id from the parent.

Here there is no injection used - you just use the already existing object - much faster and uses much less memory for large libraries.

Still the chicken/egg pops into play. Would want to use jQuery to catch document ready and this does not work in my initial tests - so more work to be done even with jQuery.

Pout....
Try to do that in Ext and you will quickly find many references to document in the code with no parameter to override. So while this idea seems great to me, it does not work well with Ext from my testing. Ext.get looks at document and I can find no way to make it not.

Hope that makes since, I'll post more simple html code when I have something working in that arena.

genius551v
18 Apr 2007, 11:15 AM
this solution is for loading with base in iframe, definitively you discard the option to load dynamically in a Div through LOAD? then in conclusion you go away better by the option of iframes?

genius551v

Joe
18 Apr 2007, 11:55 AM
I am not disregarding anything at this point - just was making a note that I do agree with the assertion that injection is not saving memory and providing some more details on my findings.

I am still using Ajax loads into Content Panels as choice one. I find that cleaning up after components like the tree and grid, even layout are making things tough. I have yet to find a way to load a grid into a content panel, then remove everything to free up all memory - the more you load, the memory is used,even going through many hoops trying to "kill everything".

I have yet to see an example of someone loading a grid,destroying it, creating another one ten times - with no extra memory used. I am VERY interested in a sample like this from anyone. In fact, no Ajax in the process even - just load a grid into a div, destroy and recreate it 10 times. May work in FireFox but in I.E. 6, I have not been able to make this happen yet. May be an issue with how I.E. 6 works, but still an issue for my wide audience.

For this reason I have been experimenting with iframe to see if there are any memory advantages.

In doing these experiments I am finding stuff out and posting here in hopes we can conclude on when to use what option and why.

Hope that helps :)

Wolfgang
18 Apr 2007, 5:17 PM
Joe, I really appreciate the documenation of your findings and conclusions.

Belgabor
18 Apr 2007, 6:44 PM
Personally I think it all comes up to the usage model of the app. Iframe pages eat more memory (which could be optimizied by a modularized injection approach) but can be discarded leakfree (at least as leakfree as possible from JS). Ajax pages do not eat duplicate toolkit memory but probably cannot be freed without leaking memory. So if the user is likely to have lots of pages open but rarely closes/reopens them: Ajax is better. Low number but high fluctuation: Probably iframes are better.

The other thing I'm not to sure of is whether all that manual evalling for injection might not be a possible security risk.

Joe
20 Apr 2007, 5:52 AM
Great summary, I have come to the same conclusions all around - right down to wondering about the security risk of injection.

I assume if we were way off base - someone from the team or elsewhere would chime in.

If we are way off base - please chime in :)

Cheers

TheNalex
23 Apr 2007, 10:37 AM
I was wondering, if you do something like this :
1/ use an XHR call to get your content
2/ your XHR returns html contents
3/ get en new documentFragement()
4/ put the content on the fragment using innerHTML
5/ place the fragment on your DOM app (replace a div or whatever else)

Joe
24 Apr 2007, 6:36 AM
That process seems similar to the Ajax pull method. Do you have code samples?