Это будет следствием вопроса, который я опубликовал на прошлой неделе: Простой jQuery Ajax вызывает утечку памяти в Internet Explorer
Мне нравится синтаксис jquery и все его приятные функции, но у меня возникли проблемы со страницей, которая автоматически обновляет ячейки таблицы через ajax-вызовы, утечка памяти.
Итак, я создал две простые тестовые страницы для экспериментов. Обе страницы выполняют ajax-вызов каждые 0,1 секунды. После каждого успешного вызова ajax счетчик увеличивается и DOM обновляется. script останавливается после 1000 циклов.
Один использует jquery для вызова ajax и для обновления DOM. Другой использует API Yahoo для ajax и делает document.getElementById(...). InnerHTML для обновления DOM.
В версии jquery плохо протекает память. Запуск в капельке (на XP Home с IE7) начинается с 9 МБ и заканчивается примерно на 48 МБ, при этом память растет линейно все время. Если я прокомментирую строку, которая обновляет DOM, она по-прежнему заканчивается на 32 МБ, предполагая, что даже простые обновления DOM утечки значительного объема памяти. Версия не-jquery начинается и заканчивается примерно на 9 МБ, независимо от того, обновляет ли она DOM.
Есть ли у кого-нибудь хорошее объяснение того, что приводит к тому, что jquery просачивается так плохо? Мне что-то не хватает? Есть ли циркулярная ссылка, о которой я не знаю? Или у jquery возникают серьезные проблемы с памятью?
Вот источник для протекающей (jquery) версии:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('jquery', '1.4.2');
</script>
<script type="text/javascript">
var counter = 0;
leakTest();
function leakTest() {
$.ajax({ url: '/html/delme.x',
type: 'GET',
success: incrementCounter
});
}
function incrementCounter(data) {
if (counter<1000) {
counter++;
$('#counter').text(counter);
setTimeout(leakTest,100);
}
else $('#counter').text('finished.');
}
</script>
</head>
<body>
<div>Why is memory usage going up?</div>
<div id="counter"></div>
</body>
</html>
И вот небезопасная версия:
<html>
<head>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/event/event-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/connection/connection_core-min.js"></script>
<script type="text/javascript">
var counter = 0;
leakTest();
function leakTest() {
YAHOO.util.Connect.asyncRequest('GET',
'/html/delme.x',
{success:incrementCounter});
}
function incrementCounter(o) {
if (counter<1000) {
counter++;
document.getElementById('counter').innerHTML = counter;
setTimeout(leakTest,100);
}
else document.getElementById('counter').innerHTML = 'finished.'
}
</script>
</head>
<body>
<div>Memory usage is stable, right?</div>
<div id="counter"></div>
</body>
</html>