Устранение утечек памяти в приложениях JavaScript может быть сложным процессом. В этой статье я покажу вам, как я исправил утечку памяти в моем приложении.

В заголовке моего приложения я использовал «таймер», который обновляется каждую секунду с помощью метода setInterval и каждые 30 секунд с сервера.

//onUpdate calls from Server
onUpdate: function (updateInfo) {
  ...
  clearInterval(t);
  renderTime();
  //Call every secand
  t = setInterval(renderTime, 1000); 
}
function renderTime() {
  const
    date = new Date(time),
    hh = twoDigits(date.getHours()),
    mm = twoDigits(date.getMinutes()),
    ss = twoDigits(date.getSeconds());
  element.innerHtml = hh + ':' + mm + ':' + ss;
  time += 1000;
}

После записи производительности в инструментах разработчика Chrome в течение 95 секунд я обнаружил, что количество узлов DOM увеличилось с 2089 до 2275 узлов.

Я увеличил масштаб одного из блоков и нашел функцию, которая вызвала эту проблему.

Вы можете увидеть функцию «renderTime» на следующем изображении, отмеченном синей рамкой.

Я искал в Google об этой проблеме, я узнал, меняю ли я «innerHtml» на «firstChild.data» Моя проблема будет исправлена.

element[0].firstChild.data = hh + ':' + mm + ':' + ss;

После записи производительности в инструментах разработчика Chrome во второй раз я вижу, что узлы DOM не увеличиваются.

Затем я создал тестовый пример на jsperf.com для измененной строки. Увидев результат, я был поражен тем, что производительность «firstChild.data» лучше, чем «innerHtml».

Вы можете проверить это по этой ссылке: https://jsperf.com/change-element-inner-text

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

Основная проблема с такими методами, как .text () в JQuery, или .innerHTML () в HTML DOM, или даже .innerText () и .textContent (), заключается в том, что все они создают новый текстовый узел (даже если он уже существует). В частности, все перечисленные выше методы начинаются с удаления всех дочерних узлов DOM, включая уже существующий текстовый узел (это также делается с помощью реализаций «innerHTML», «innerText» и «textContent»).

Это оставляет элемент контекста (DIV, в вашем случае) пустым, без каких-либо дочерних элементов. Затем они создают новый дочерний узел типа text node, присваивая ему новый текст и добавляя его к элементу контекста. innerHTML, кроме того, пытается проанализировать входную строку HTML и построить из нее фрагмент DOM.

Самый быстрый из известных мне способов замены существующего текстового узла следующий: node.firstChild.data = ‘Your text’.

Это все, что у меня есть по этой теме. Спасибо за прочтение!