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

Почему опасно хранить данные как атрибут элемента?

Я продолжаю читать то же самое:

"Сохранение значений свойств непосредственно на элементах DOM является рискованным из-за возможных утечек памяти".

Но кто-нибудь может объяснить эти риски более подробно?

4b9b3361

Ответ 1

(По атрибуту, я предполагаю, что вы ссылаетесь на свойства на элементах DOM.)

Безопасны ли пользовательские свойства элементов DOM?

Некоторые браузеры не очень хорошо очищают элементы DOM при их уничтожении. Поэтому ссылки на другие элементы, один и тот же элемент или большие наборы данных были сохранены, что вызвало утечки. Я считаю, что это в значительной степени разрешено в новых браузерах.

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


Использует jQuery .data() безопасную альтернативу?

Не особенно. Хранение данных с использованием хранилища пользовательских данных jQuery имеет собственный потенциал для утечек памяти, и, к сожалению, они не просто влияют на старые браузеры.

Чтобы избежать утечек, вам нужно быть абсолютно уверенным, что вы очищаете элемент .data() при уничтожении элемента. Это автоматически, когда вы используете jQuery для уничтожения элемента, но если вы этого не сделаете, у вас будут утечки памяти, которые влияют на каждый браузер.


Какие примеры могут вызвать утечки?

Скажем, что существует цепочка .data(), связанная с элементом #foo. Если мы используем методы jQuery для удаления элемента, мы в безопасности:

$("#foo").remove(); // associated .data() will be cleaned automatically

Но если мы это сделаем, у нас есть совместимая с кросс-браузером утечка:

var foo = document.getElementById("foo");
foo.parentNode.removeChild(foo);

Или, если #foo является потомком какого-либо другого элемента, содержимое которого очищается без jQuery, это будет одна и та же проблема.

otherElement.innerHTML = "";

В обоих случаях jQuery не использовался для удаления #foo, поэтому его .data() постоянно отключается от элемента, а наше приложение имеет утечку.


Итак, если я никогда не использую DOM API напрямую, я в безопасности?

Вы безопаснее, но это может произойти, если мы загрузим более одной библиотеки манипуляций DOM. Подумайте, что jQuery помогает нам сделать это со следующим кодом:

var $jq = jQuery.noConflict();

Теперь мы можем разрешить $ ссылаться на prototypejs или mootools, а на jQuery ссылается $jq.

Проблема в том, что эти другие библиотеки не будут очищать данные, установленные jQuery, потому что они не знают об этом.

Итак, если jQuery имеет некоторые данные на #foo, а mootools используется для уничтожения этого элемента, у нас есть утечка памяти.


Что делать, если я никогда не использую .data() в jQuery? Это делает меня безопасным?

К сожалению, нет. jQuery использует тот же механизм .data() для хранения других данных, таких как обработчики событий. Поэтому, даже если вы никогда не делаете вызов .data() для связывания некоторых пользовательских данных с элементом, вы все равно можете иметь утечки памяти, вызванные приведенными выше примерами.

В большинстве случаев вы можете не заметить утечки, но в зависимости от характера кода они могут в конечном итоге стать достаточно большими, чтобы быть проблемой.

Ответ 2

Согласно документации jQuery:

В Internet Explorer до версии 9 с помощью .prop() установите DOM элемент для чего-либо, кроме простого примитивного значения (number, string или boolean) может вызвать утечку памяти, если свойство не удаляется (с использованием .removeProp()) перед удалением элемента DOM из документа. Безопасное задание значений объектов DOM без памяти утечки, используйте .data().