Подтвердить что ты не робот

JQuery.html() метод утечки памяти?

Я создаю игру с циклом requestAnimationFrame, который включает вызов метода jQuery html(). Он просто обновляет текст в окне состояния рядом с действием игры.

Я отмечаю с монитором хронологии Chrome, что узлы DOM поднимаются и поднимаются вверх, и тысячи в минуту! И когда я меняю свой код на:

// creates a ton of DOM nodes
$("#readout").html(data);

к

// DOM nodes does not increase over time
document.getElementById('readout').innerHTML = data;

"утечка памяти" исчезает.

4b9b3361

Ответ 1

Короткий ответ: Нет.

Длинный ответ. Вероятно, в вашей странице/коде есть что-то еще.

Утечка памяти обычно вызвана круговой ссылкой между движком Javascript и DOM. Например:

var div = document.getElementById('divId');
div.onclick = function() {
    doSomething(div);
};

script получает ссылку на div на странице. Пока все в порядке. Следующая строка назначает функцию обработчику событий в DOM, создавая ссылку из DOM на механизм Javascript - на полпути к утечке. Тело функции использует тег, который создает Closure - ссылка на тег хранится с функцией для будущих вызовов к ней. Это завершает круговую ссылку между тегом → функцией (DOM → JS) и тегом function → (JS → DOM), и поэтому 2 будет сидеть в памяти до тех пор, пока процесс браузера не будет уничтожен.

Итак, для того, чтобы вы указали какую-либо строку кода, которую вы упомянули, она должна была бы исключать теги, у которых были события, прикрепленные, как указано выше (или данные, которые следуют аналогичной схеме). Но jQuery.html(string) не подходит для этого:

// Remove element nodes and prevent memory leaks
elem = this[i] || {};
if ( elem.nodeType === 1 ) {
    jQuery.cleanData( getAll( elem, false ) );
    elem.innerHTML = value;
}

Итак, он перебирает все теги внутри тега, на котором запущен .html(string), и запускает на них cleanData(), что в свою очередь делает это:

jQuery.removeEvent( elem, type, data.handle );

Таким образом, предотвращение утечки.

Итак, чтобы утечка памяти с помощью этого метода, а не встроенный браузер .innerHTML, вам придется запускать очень туманную ошибку браузера (кажется, маловероятно), или, скорее всего, что-то еще происходит, перепутав его для jQuery.html(string).

Ответ 2

Всегда используйте .empty().html(...) вместо .html()

.empty() отсоединяет прослушиватели событий от объектов DOM, которые вы собираетесь удалить, и изящно удаляет их.