Alexander Cosman
Alexander Cosman

Reputation: 1137

Memory leak with KnockoutJS foreach binding

I run into an issue when running my KnockoutJS v3.4.2 (test) application in Google Chrome.
The memory usage of my page keeps increasing.

The test code is a very simple piece of code, that changes the items in an observable array every second:

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);

Memory usage:

Am I doing something wrong in this code snippet? Or would this be a bug in Google Chrome or KnockoutJS?

Upvotes: 11

Views: 903

Answers (2)

Alexander Cosman
Alexander Cosman

Reputation: 1137

Apparently this was a browser issue.

When I now run my test project the memory doesn't increase.
The test project can be found here: https://github.com/knockout/knockout/issues/2223

Solved in Google chrome version '58.0.3029.110'.

Upvotes: 1

itcropper
itcropper

Reputation: 772

Even though you're replacing the array in the observable, they're still attached to the DOM. You would need to manually remove them prior to adding new elements to the array.

Something like this:

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);

See #2 in this post: https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

Upvotes: 0

Related Questions