Добавляет ли removeEventListener прослушиватель событий? - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь выяснить, может ли сборщик мусора JavaScript Chromes собирать прослушиватели событий элементов, которые удалены из DOM, даже если не вызывается removeEventListener.Для этого я использую Google Chrome DevTools (вкладка «Производительность») для проверки кривой «Слушатели» на графике.

Я разработал простой код, который создает N делений при нажатии на кнопку, а затем добавляет к каждомуодин из них слушатель событий.Затем, когда я нажимаю на один из элементов div, все они удаляются из DOM и:

-Сценарий 1: не вызывать removeEventListener, чтобы выяснить, может ли сборщик мусора удалить их самостоятельно (поскольку элементов больше не было в DOM).

-Сценарий 2: вызовите removeEventListener для явного удаления своих слушателей.Сравнивая оба сценария, я подумал, что если результат был одинаковым, то сборщик мусора фактически удаляет слушателей в обоих случаях.

На вкладке производительности оба сценария выполнялись следующим образом: 1) Нажмите кнопку записи2) Принудительно собрать мусор 3) Нажать на кнопку, чтобы создать div. 4) Нажать на div, чтобы удалить их из DOM (и во втором сценарии удалить их слушателей). 5) Принудительно собрать мусор. 6) Остановить запись.

Результат, который я получил, поднял еще несколько вопросов.

-Сценарий 1: начинается с 1 слушателя (кнопки), затем добавляет N слушателей (1 для каждого div).После окончательной сборки мусора остаются 2 прослушивателя событий, прослушиватель кнопки и еще один неизвестный.

Вопрос 1: что это за неизвестный прослушиватель событий и откуда он поступает после мусорасборщик смог удалить N слушателей (или, возможно, N-1)?

-Сценарий 2: так же, как сценарий 1, начинается с 1, затем добавляет N слушателей, но странно, когда вызывается removeEventListener, N других слушателейдобавлено, так что теперь у нас есть 1 + 50 + 50 = 101 слушателей.Но в отличие от первого сценария, после последнего сбора мусора остается только 1 слушатель (кнопка).

Вопрос 2: Почему добавляются прослушиватели событий при вызове removeEventListener, и это может повлиять на производительность?

var n = 50;
var divs = [];

btn = document.createElement("button")
btn.style.height = "50px";
document.body.appendChild(btn);
btn.addEventListener("click",f);

function f(){
    for(var i=0; i<n; i++){
        divs[i] = document.createElement("div")
        document.body.appendChild(divs[i]);
        divs[i].addEventListener("click",g);
        divs[i].style.height = "5px";
        divs[i].style.backgroundColor = "blue";
    }
    console.log("created " + n + " divs with event listeners")
};

function g(){
    for(var i=0; i<n; i++){
        divs[i].removeEventListener("click",g);     //called only in scenario 2
        divs[i].parentElement.removeChild(divs[i]);
    }
    console.log("remove " + n + " divs and their event listeners")
    divs = null;
}
...