views:

260

answers:

1

Hi,

I'm loading in content using an iframe via a menu with jquery which is updating the 'src' attribute of the iframe to then load in the desired page. Each of the pages have their own javascript includes and heavy content.

The code is as follows:-

$(document).ready(function() {
    loadPage('main.php');
});

function loadPage(url) {
    $('#applicationFrame').attr('src', url);
}

And the iframe on the index page looks as follows:-

<iframe id="applicationFrame" application="yes" trusted="yes" frameborder="0" />

(Side note: I realise that the iframe here is taking nonstandard attributes, but this is an internal intranet application running in one of these Microsoft HTA's in which they do mean something.)

Anyway, the menu items are just calling javascript:loadPage('whatever.php') in order to load in whatever content is needed.

The problem I'm facing is that on each subsequent page click of the menu the frames are leaking memory until eventually the entire app slows to a crawl. sIEve reports the following:-

leaks

The leaks column is ascending here with every click (21 -> 44 -> 65) etc.

Examining the leaks inspector shows:

inspector

Which looks to me like it is just the entire iframed content which has leaked.

Is there anyway to avoid this? Am I missing something? I've found a similar issue here that the dojo framework has had, but trying the suggested solutions hasn't seemed to work. I've also tried a bunch of other things as pasted here but to no resolve.

This only seems to (surprise) affect IE6 which is really the only target audience of the application.

+1  A: 

Had a little time at hand and tried a jQuery less variant. Doesn't seem to leak anymore according to SIEve.

function pos(obj) {
    var curleft = 0;
    var curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
    }
    obj = null;
    return {left:curleft, top:curtop};
}

function loadPage(url) {
    var y = document.getElementById('container');
    var x = document.getElementById('applicationFrame');
    var p = pos(y);
    if (x.src) {
        var tmp = y.cloneNode(false);
        var tmpIF = x.cloneNode(false);
        tmpIF.src = url;
        tmp.appendChild(tmpIF);
        tmp.style.position = 'absolute';
        tmp.style.visibility = 'hidden';
        tmp.style["z-index"] = 20;
        tmp.style.top = p.top;
        tmp.style.left = p.left;
        y.id = "delete";
        x.id = "deleteApplicationFrame";
        document.getElementsByTagName("body")[0].appendChild(tmp);
        tmpIF = null; tmp = null;
    }
    setTimeout("document.getElementById('applicationFrame').style.visibility = 'visible'; var i = document.getElementById('deleteApplicationFrame'); i = i.contentDocument || i.contentWindow.document; i.documentElement.parentNode.removeChild(i.documentElement); i=null; i=document.getElementById('delete'); i.parentNode.removeChild(i); i=null;", 500);
    y = null; x = null; p = null;
}

<div id="container">
    <iframe id="applicationFrame" application="yes" trusted="yes" frameborder="0" src="main.php"/>
</div>


Very hard to tell what could possibly be going on without knowing the whole application. Especially IE6 is a b..ch with memory leaking.

A few reading links

Understanding and Solving Internet Explorer Leak Patterns

Fixing Leaks

Memory Leakage in Internet Explorer - revisited


Just a thought, AFAIK the behavior when setting src to a different value isn't really specified in the W3C HTML DOM specification or is it (link anyone?)?

I suggest that you set an initial src="main.php" value on the iframe instead of using loadPage('main.php'); and set a name for the iframe.

Ideally your menu items are <a> tags then you could test using <a href="notmain.php" target="nameOfYourIFrame">FooBar</a> instead of the javascript based solution

jitter
Hi, thanks for the response. I realise it is a pretty horrible issue to try and sort out. Oh, and thanks for the links which I've seen before.As for the menu items, I tried your suggestion of using the anchor tags which got my hopes up (I was just using onclick events before), though unfortunately it seems to be leaking the same way (but not as bad).Setting src="main.php" as default has reduced the number of leaks on the first click which has changed to '1' rather than '21' in the screenshot which has helped. Problem still remains the more sections you click though.Ready to rewrite(!)
Gavin Gilmour
Hi check expanded answer
jitter
Wow, this works perfectly. Much appreciated for this, it has saved me tearing my hair out just that little bit less with IE6.
Gavin Gilmour