Устранение утечек памяти в приложениях 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’.
Это все, что у меня есть по этой теме. Спасибо за прочтение!