Какова цель $ .cache в jQuery? - PullRequest
       3

Какова цель $ .cache в jQuery?

15 голосов
/ 16 февраля 2012

Я вижу, что обработчики событий, зарегистрированные через .on(), хранятся в $.cache. Я также вижу, что обработчики событий также хранятся в $(elem).data().

Объекты, хранящиеся в $.cache, относятся к узлам DOM, на которых зарегистрированы события. Это приводит к утечке памяти, когда узлы DOM отсоединены, и это делает .off() вызовы обязательными.

У меня есть ситуация, когда я не знаю, когда отсоединяется узел DOM (к которому я подключил обработчик событий). Хотя я могу удерживать ссылку на этот узел DOM в своем коде и вызывать .off() для очистки, это нехорошо, потому что непросто узнать, когда удаляется узел DOM.

Каков наилучший способ сделать это?

Ответы [ 2 ]

16 голосов
/ 16 февраля 2012

«Какой лучший способ сделать это?»

Если вы собираетесь использовать jQuery, вы должны использовать его API для удаления элементов, и вы должны использовать правильные методы, иначе, как вы заявили, у вас будут утечки памяти.

Если вы не знаете, когда удаляется узел DOM и если он вызывает утечку, я предполагаю, что это означает, что вы используете другую библиотеку наряду с jQuery. Это просто не очень хорошая идея по этой самой причине.

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


«Какова цель $.cache в jQuery?»

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

Если вы удалите элемент без jQuery, связанные данные в $.cache будут потеряны.

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

6 голосов
/ 15 июля 2014

Я столкнулся с подобной ситуацией, когда Knockout используется для добавления и удаления деревьев dom из документа.Однако jquery используется для присоединения слушателей событий к этим деревьям домена.Когда knockout удаляет элементы dom из документа, слушатели не освобождаются, поэтому дерево dom никогда не подходит для сборки мусора.Мы добавили функцию очистки, которая проходит через jquery $ .cache каждый раз, когда изменяется хеш, и находит даже обработчики, связанные с деревьями, которых нет в документе.Затем он освобождает слушателей, таким образом, делая дерево dom пригодным для сбора мусора и исправляя большинство утечек, которые мы видим, т.е. обход в обход приложения, использовавшего утечку 13 МБ, теперь он пропускает всего 3 МБ с этими изменениями на месте.

for (var i in $.cache) {
            if ($.cache.hasOwnProperty(i)) {

                if ($.cache[i].handle && $.cache[i].handle.elem && document !== $.cache[i].handle.elem && !jQuery.contains(document, $.cache[i].handle.elem)) {
                    //we have an event handler pointing to a detached dom element!
                    //this is a memory leak as this detached dom element cannot be garbage collected until
                    //all references to it are removed. So lets delete the event handler to get memory back!
                    var orphan = $($.cache[i].handle.elem);
                    $('body').append(orphan);
                    orphan.off();
                    orphan.remove();
                    orphan = null;
                }
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...