Jeśli element DOM zostanie usunięty, czy jego detektory również zostaną usunięte z pamięci?
źródło
Jeśli element DOM zostanie usunięty, czy jego detektory również zostaną usunięte z pamięci?
Zwykły JavaScript
Jeśli usunięty element DOM jest pozbawiony referencji (brak referencji do niego wskazujących), to tak - sam element jest odbierany przez moduł wyrzucający elementy bezużyteczne, a także powiązane z nim procedury obsługi / nasłuchiwania zdarzeń.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null;
// A reference to 'b' no longer exists
// Therefore the element and any event listeners attached to it are removed.
Jednak; jeśli istnieją odniesienia, które nadal wskazują na ten element, element i detektory zdarzeń są zachowywane w pamięci.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
// A reference to 'b' still exists
// Therefore the element and any associated event listeners are still retained.
jQuery
Można byłoby założyć, że odpowiednie metody w jQuery (takie jak remove()
) działałyby dokładnie w ten sam sposób (biorąc pod uwagę, że remove()
zostały napisane przy użyciu removeChild()
np.).
To jednak nie jest prawda ; biblioteka jQuery faktycznie ma wewnętrzną metodę (która jest nieudokumentowana i teoretycznie może być zmieniona w dowolnym momencie) o nazwie cleanData()
(oto jak ta metoda wygląda ), która automatycznie usuwa wszystkie dane / zdarzenia związane z elementem po usunięciu z DOM (czy to przez. remove()
, empty()
, html("")
itp).
W starszych przeglądarkach - szczególnie w starszych wersjach IE - występują problemy z wyciekiem pamięci, ponieważ detektory zdarzeń przechowują odniesienia do elementów, do których zostały dołączone.
Jeśli chcesz bardziej dogłębnego wyjaśnienia przyczyn, wzorców i rozwiązań zastosowanych w celu usunięcia wycieków pamięci starszej wersji IE, w pełni zalecam przeczytanie tego artykułu MSDN na temat zrozumienia i rozwiązywania wzorców wycieków w programie Internet Explorer.
Kilka innych artykułów na ten temat:
Ręczne usuwanie słuchaczy prawdopodobnie byłoby dobrym nawykiem, aby się w tym przypadku przyzwyczaić (tylko jeśli pamięć jest tak ważna dla twojej aplikacji i faktycznie atakujesz takie przeglądarki).
remove
metody. przez większość czasu DOM jest po prostu całkowicie usuwany. (jak linki turbo lub coś takiego). Zastanawiam się, jak wpłynie to na pamięć, jeśli to zrobiędocument.body.innerHTML = ''
...w odniesieniu do jQuery:
Odniesienie: http://api.jquery.com/remove/
.remove()
Kod źródłowy jQuery v1.8.2 :najwyraźniej używa jQuery
node.removeChild()
Zgodnie z tym: https://developer.mozilla.org/en-US/docs/DOM/Node.removeChild ,
The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.
tzn. detektory zdarzeń mogą zostać usunięte, ale
node
nadal istnieją w pamięci.źródło
removeChild
co nie byłoby tak proste w przypadku programów obsługi . Oba również zwracają ci odniesienie, które możesz zachować, aby ponownie dołączyć (w takim przypadku oczywiście pozostaje w pamięci) lub rzucić drogę (w którym to przypadku jest on ostatecznie odbierany przez GC i usuwany).Nie wahaj się obserwować sterty, aby zobaczyć wycieki pamięci w procedurach obsługi zdarzeń przechowujących odwołanie do elementu z zamknięciem oraz elementu przechowującego odwołanie do procedury obsługi zdarzeń.
Śmieciarka nie lubi okrągłych odniesień.
Przypadek przecieku pamięci: przyznaj, że obiekt ma odwołanie do elementu. Ten element ma odniesienie do modułu obsługi. I handler ma odwołanie do obiektu. Obiekt odnosi się do wielu innych obiektów. Ten obiekt był częścią kolekcji, którą Twoim zdaniem wyrzuciłeś, odwołując ją do swojej kolekcji. => cały obiekt i wszystko, do czego się odnosi, pozostanie w pamięci aż do wyjścia ze strony. => musisz pomyśleć o kompletnej metodzie zabijania dla swojej klasy obiektów lub zaufać np. ramce mvc.
Ponadto nie wahaj się skorzystać z części Drzewo zatrzymujące narzędzi programistycznych Chrome.
źródło
Po prostu rozszerzam inne odpowiedzi ...
Programy obsługi zdarzeń delegowanych nie zostaną usunięte po usunięciu elementu.
Teraz sprawdź:
źródło
W związku z
jQuery
tym następujące typowe metody usuwają również inne konstrukcje, takie jak procedury obsługi danych i zdarzeń:usunąć()
pusty()
html ()
źródło
Tak, śmieciarz również je usunie. Jednak nie zawsze tak jest w przypadku starszych przeglądarek.
źródło