Как очистить память JSONP в Internet Explorer - PullRequest
6 голосов
/ 09 марта 2011

Я новичок в разработке JSONP и обнаружил, что IE 7/8 не будет очищать память, которую занимает скрипт JSONP.Это приводит к очень высокому потреблению памяти на моей странице после нескольких часов работы.

Я просмотрел Интернет и обнаружил, что большинство исправлений основаны на подсказке Neil Fraser .В блоге говорится, что вам нужно удалить все свойства скрипта с помощью кода, подобного

    var tmp;
    while (tmp = document.getElementById('JSONP')) {
        tmp.parentNode.removeChild(tmp);

        // this deletion will create error in IE.
        for (var prop in tmp) delete tmp[prop];
        tmp = null;
    }

К сожалению, удаление приведет к ошибке «Объект не поддерживает это действие» в IE, и это приведет кне освободить память.

Поэтому мой вопрос заключается в том, как на самом деле освободить память моего скрипта JSONP?

Я поставил свой код тестирования следующим образом:

Testing.html

<html><head></head><body><script>
var script,
head = document.getElementsByTagName('head')[0],
loadCount= 0,
uuid= 1,
URL= "memleaktest.js?uuid=",

clearConsole = function() {
    var con= document.getElementById("console");
    while (con.childNodes.length) 
        con.removeChild(con.childNodes[0]);
},

log = function(msg) {
    var div= document.createElement("DIV"),
        text= document.createTextNode(msg),
        con= document.getElementById("console");

    div.appendChild(text);
    con.appendChild(div);
},

test = { "msg" : null, "data" : null };

var loaded= function() {
    if (!test.msg) 
        return setTimeout(loaded,10);

    log("loaded #" + loadCount + ": " + test.msg);

    var tmp;
    while (tmp = document.getElementById('JSONP')) {
        tmp.parentNode.removeChild(tmp);

        // not working in IE 7/8
        // for (var prop in tmp) delete tmp[prop];
        tmp = null;
    }

    test.msg = test.data = null;

    if (--loadCount) 
        setTimeout(load, 100);
};

var load = function(){
    var url= URL + (uuid ++);
    log("load via JSONP: "+url);

    script= document.createElement('script');       
    script.id = 'JSONP';
    script.type = 'text/javascript';
    script.charset = 'utf-8';
    script.src = url;
    head.appendChild(script);
    setTimeout(loaded,1000);
};
</script>
<div>
<button onclick="loadCount=3; load();" name="asd" value="asdas">jsonp load</button>
<button onclick="clearConsole();" name="asd" value="asdas">clear Console</button>
</div>
<div id="console"></div>
</body></html>

memoryleaktest.js

test.msg = "loaded #"+loadCount;
test.data = "test data with 1MB size";

Можно воссоздать утечку памяти, вставив код в два файла и открыв Testing.html.

Я использовал Drip для отслеживания утечек, и в Drip вы можете видеть, что память продолжает увеличиваться, а "<" script ">" не удаляется.

Большое спасибо за любую помощь!

1 Ответ

2 голосов
/ 09 марта 2011

На ваш вопрос уже дан ответ в сообщении в блоге, на которое вы ссылаетесь.См. Последний абзац.

Как обычно, IE - странный браузер, который требует особого случая.IE не любит удалять собственные свойства из узлов DOM.К счастью, это не имеет значения, поскольку IE позволяет повторно использовать теги скрипта.Просто измените свойство SRC, и он сразу же получит новую страницу.Таким образом, в IE требуется только один тег script.

Приведенный код работает во всех браузерах, кроме IE, и в IE это не проблема, поскольку вы можете просто изменить свойство src тега script иэто возобновится.Таким образом, ваш код (только для IE) будет просто:

var script = document.getElementById('JSONP');
if (!script) {
  [create it once]
}
script.src = URL + (uuid ++);
...