Утечка памяти с помощью привязки KnockoutJS foreach
Я столкнулся с проблемой при запуске приложения NockoutJS v3.4.2 (test) в Google Chrome.
Использование моей страницы памяти увеличивается.
Тест-код - очень простой фрагмент кода, который меняет элементы в наблюдаемом массиве каждую секунду:
HTML:
<html>
<head>
<title>KnockoutJS</title>
</head>
<body>
<h1>Foreach test</h1>
<ul id="ul-numbers" data-bind="foreach: { data: listOfItems }">
<li>
<span data-bind="text: $data"></span>
</li>
</ul>
<script type="text/javascript" src="./lib/knockout.js"></script>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>
JavaScript:
var vm = {
listOfItems: ko.observableArray()
};
window.setInterval(function updateList(){
var array = [];
for(var i = 0 ; i < 1000; i++){
var num = Math.floor( Math.random() * 500);
array.push(num);
}
vm.listOfItems(array);
}, 1000);
ko.applyBindings(vm);
Использование памяти:
-
В Firefox использование памяти не увеличивается:
начало: 459.6 МБ --- > После + - 1 час: 279.4 МБ
-
В хроме использование памяти увеличивается (память отдельных вкладок):
начало: 52.912 МБ --- > После + - 1 час: 566.120 МБ
- В краю использование памяти также увеличивается (память отдельных вкладок):
начало: 109,560 МБ --- > После + - 1 час: 385.820 МБ
Я делаю что-то неправильно в этом фрагменте кода? Или это будет ошибкой в Google Chrome или KnockoutJS?
Ответы
Ответ 1
По-видимому, это была проблема с браузером.
Когда я запускаю свой тестовый проект, память не увеличивается.
Проект тестирования можно найти здесь: https://github.com/knockout/knockout/issues/2223
Решено в версии Google chrome версии '58.0.3029.110 '.
Ответ 2
Даже если вы заменяете массив в наблюдаемом, они все еще привязаны к DOM. Вам нужно будет вручную удалить их до добавления новых элементов в массив.
Что-то вроде этого:
var vm = {
listOfItems: ko.observableArray()
};
window.setInterval(function updateList(){
var array = [];
vm.listOfItems.removeAll();//<--this is the important line
for(var i = 0 ; i < 1000; i++){
var num = Math.floor( Math.random() * 500);
array.push(num);
}
vm.listOfItems(array);
}, 1000);
ko.applyBindings(vm);
См. # 2 в этом сообщении: https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/