Динамические страницы и добавление сторонних библиотек приводят к утечке памяти при повторном использовании в javascript
изучаю js и столкнулся с такой ситуацией есть html страница с динамическим изменением контента с помощью ajax запросов и для удобства использую сторонние библиотеки для реализации той или иной функциональности на сайте, это может быль что угодно(вывод информации в виде графы, редактор комментариев, загрузчик и редактор картинок и тд) так вот, как известно что бы работать с элементом (тегом) нужно его идентифицировать то есть он должен быть уже на странице, выход что стороннюю библиотеку нужно инициализировать после добавления элемента, а если страницу менять то выходит инициализированную библиотеку нужно деактивировать\удалить а потом снова пользователь захотел поработать с этим элементом, его снова надо создать и снова инициализировать библиотеку а там (в библиотеке)еще может и быть и события какие то оставаться утечка памяти и тд Коротко говоря я набросал максимально маленький пример для наглядности
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Memory and event</title>
</head>
<body>
<div id="test_div" style="border: 1px solid #ddd;">
<h2> страница сайта </h2><br>
<div id="content">
<h2>Welcome</h2>
</div>
</div>
<br>
<br>
<br>
<br>
<h1>Menu</h1>
<button id="home">Home</button><br>
<button id="page">Form edit</button>
<script>
// КОД В ДРУГИХ ФАЙЛАХ
// *************************************************************
// какая то библиотека\фрейворк из интернета для работы с формой
// ====================================================
// <script src="https://CDN.blabla .... >
// я не знаю как она внутри реализованна
class StoronnyayaBiblioteka {
constructor(buttonId, inputId) {
this.button = document.getElementById(buttonId);
const input = document.getElementById(inputId);
this.button.addEventListener("click", (event) => {
event.preventDefault()
alert('click button id = buttonId \n message: ' + input.value);
});
}
}
// ====================================================
// мои файлы для сайта
// ----------------------------------------------------
// ---- myapihome.js ------
class MyApiHome {
constructor() {
/*...*/ }
init() {
/*...*/ }
destroy() {
/*...*/ }
}
// ---- myapipage.js ------
class MyApiPage {
constructor() {
this.textEditor = null;
// ...
}
init(btn, inp) {
this.textEditor = new StoronnyayaBiblioteka(btn, inp);
// ...
}
destroy() {
this.textEditor = null;
// ...
}
}
// ----------------------------------------------------
// *************************************************************
// ОСНОВНОЙ ФАЙЛ СКРИПТА ДЛЯ СТРАНИЦЫ
// ----- app.js -------
// import MyApiHome from './myapihome.js';
// import MyApiPage from './myapipage.js';
let APPCONTENT = null;
document.addEventListener('DOMContentLoaded', (e) => {
// menu
document.getElementById("home").addEventListener("click", (e) => {
dinamicEditPageSite("home");
});
document.getElementById("page").addEventListener("click", (e) => {
dinamicEditPageSite("page");
});
APPCONTENT = new MyApiHome();
if (APPCONTENT)
APPCONTENT.init();
});
function dinamicEditPageSite(id) {
const content = document.getElementById("content");
content.innerHTML = "Load page...";
switch (id) {
case "home": {
// ajax загрузка страницы и создаем ее содержимое и добавляем через appendChild :)
// но для примера и так сойдеттт
content.innerHTML = "<h2>Welcome</h2>";
if (APPCONTENT) {
APPCONTENT.destroy();
APPCONTENT = null;
}
APPCONTENT = new MyApiHome();
if (APPCONTENT)
APPCONTENT.init();
}
break;
case "page": {
// ajax загрузка страницы и создаем ее содержимое и добавляем через appendChild :)
content.innerHTML = '<form action="#" method="post"> <input type="text" id="inputId" placeholder="comment..."><br> <button id="buttonId" >кнопка формы</button> </form>';
if (APPCONTENT) {
APPCONTENT.destroy();
APPCONTENT = null;
}
APPCONTENT = new MyApiPage();
if (APPCONTENT)
APPCONTENT.init("buttonId", "inputId");
}
break;
default:
break;
}
}
</script>
</body>
</html>
Вопрос: при создании и удалении объекта MyApiPage на сколько это правильно с точки зрения безопасности и утечки памяти или остатка обработчика событий(если они есть) от сторонних библиотек, реализовывая вот такое удаление this.textEditor = null; в destroy()
я могу в destroy удалить свои объекты или обработчики событий, а что делать если использую например WYSIWYG-редакторы, amCharts и тд