Ответ 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()
для связывания некоторых пользовательских данных с элементом, вы все равно можете иметь утечки памяти, вызванные приведенными выше примерами.
В большинстве случаев вы можете не заметить утечки, но в зависимости от характера кода они могут в конечном итоге стать достаточно большими, чтобы быть проблемой.