I have a strange behaviour in (at least) IE11 and Edge (minimaly in Chrome). I create an iFrame and detach it afterwards but memory keeps increasing. In this iFrame only an empty page with javaScript imports is loaded.
I found some suggestions to change src of iFrame to about:blank but it still isn't working. Has anyone an idea what is going wrong?
Edit:
I tried it with the jQuery purgeFrame plugin and changed speed and iteration count.
Since it seems to be mainly a IE11 and Edge problem we also posted it on https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8449104/
The new code for the outer frame is:
<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">
var counter =0;
/*
* jQuery purgeFrame
* A jQuery plugin to clean up Iframes and make IE happy
*
* Copyright (c) March 2014 Tom Mooney
* licensed under the MIT license, http://www.opensource.org/licenses/mit-license.php
*/
(function ($) {
$.fn.purgeFrame = function () {
var deferred = purge(this);
return deferred;
};
function purge($frame) {
var len = $frame.length
var deferred = $.Deferred();
$frame.one('load', function () {
try
{
$(this.contentWindow).empty();
len -= 1;
if (len <= 0) {
$(this).remove();
}
$frame = null;
}
finally {
deferred.resolve();
}
});
//Set src to about:blank to so that contentWindow can be manipulated on cross-domain iframes
$frame.attr('src', 'about:blank');
if ($frame.length === 0) {
deferred.resolve();
}
return deferred.promise();
}
}(jQuery));
$(document).ready(function () {
var myTimer = setInterval(
function(){
var contentContainer = $("#contentDiv");
var iFrame = $('<iframe class="contentFrame" frameborder="0" name="bla" style="overflow:auto; width: 100%; height: 100%;" src="leere.html"></iframe>');
contentContainer.append(iFrame);
$(iFrame).purgeFrame().done(function() {
console.log("deleted frame");
iFrame = null;
});
if (counter == 1000) {
clearInterval(myTimer);
}
counter++;
}, 50
);
});
</script>
</head>
<body>
<div id="contentDiv" style="width:100%; height:100%"></div>
</body>
</html>
The loaded html (leere.html)
<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
</head>
<body>
Test
</body>
</html>
Memory Usage in IE11 (3x 1000 cycles) Memory Usage in Edge (1x 1000 cycles)
I ran the webpage and used Chrome's Task Manager to monitor the memory consumption of the tab. I changed the number of intervals to 150, memory went to 84MB, stayed there for a while and then dropped back to 20MB. Memory consumption also drops after a while in IE.
My guess is that when you remove the iFrame and set the variable to null memory is not released right away but only during garbage collection after a while. As far as I know there is no way for you to forcibly instruct the browser to do garbage collection from JS. So there's nothing you can do about it other than rewrite your code to not create too many new DOM objects constantly.