Knockout.js Observable Arrays Performance
A look at knockout observable arrays performance
by vintharas
HTML
<h1>Test the Performance of Observable Arrays with Gandalf!!</h1>
<p>Add ganfalses with the buttons below...</p>
<button data-bind="click: addGandalfsesBad">Add Gandalfses Bad!</button>
<button data-bind="click: addGandalfsesGood">Add Gandalfses Good!</button>
<button data-bind="click: addLotsOfGandalfsesBad">Add Lots Of Gandalfses Bad!</button>
<button data-bind="click: addLotsOfGandalfsesGood">Add Lots Of Gandalfses Good!</button>
<button data-bind="click: clearAll">Clear all</button>
<h2>Results</h2>
<!-- ko foreach: results -->
<article>
<p>Number of elements in array: <span data-bind="text: $parent.gandalfses().length"></span></p>
<p>Number of elements added to array: <span data-bind="text: elementsAddedtoArray"></span></p>
<p>Number of notifications: <span data-bind="text: numberOfNotifications"></span></p>
<p>Time to add new items and render array: <span data-bind="text: timeToAddNewItems"></span> milliseconds</p>
</article>
<!-- /ko -->
<h2>Array of Gandalfses</h2>
<!-- ko foreach: gandalfses -->
<p><span data-bind="text:name"></span>, the <span data-bind="text: color"></span></p>
<!-- /ko -->
CSS
article{
margin-bottom: 10px;
}
article p{
margin: 0px 10px;
}
JavaScript
var ViewModel,
Result,
moreGandalfses,
lotsOfGandalfses;
ViewModel = function(){
var self = this;
self.gandalfses = ko.observableArray([{name: 'Gandalf', color: 'Grey'}]);
self.numberOfNotifications = ko.observable("");
// self.results = ko.observableArray([]);
// I have added this below to illustrate how you can set
// the context of an observable array explicitely
};
ViewModel.prototype.clearAll = function(){
var self = this;
self.gandalfses([]);
self.results([]);
};
ViewModel.prototype.addGandalfsesBad = function(){
var self = this,
newResult = new Result(self.gandalfses);
moreGandalfses.forEach(function(aGandalf){
self.gandalfses.push(aGandalf);
});
newResult.finishedAddingItems();
self.results.unshift(newResult);
};
ViewModel.prototype.addGandalfsesGood = function(){
var self = this,
newResult = new Result(self.gandalfses),
innerArray = self.gandalfses();
moreGandalfses.forEach(function(aGandalf){
innerArray.push(aGandalf);
});
// explicitely trigger notifications
self.gandalfses.valueHasMutated();
newResult.finishedAddingItems();
self.results.unshift(newResult);
};
ViewModel.prototype.addLotsOfGandalfsesBad = function(){
var self = this,
newResult = new Result(self.gandalfses);
for (var i = 0; i < 50; i++){
moreGandalfses.forEach(function(aGandalf){
self.gandalfses.push(aGandalf);
});
}
newResult.finishedAddingItems();
self.results.unshift(newResult);
};
ViewModel.prototype.addLotsOfGandalfsesGood = function(){
var self = this,
newResult = new Result(self.gandalfses),
innerArray = self.gandalfses();
for (var i = 0; i < 50; i++){
moreGandalfses.forEach(function(aGandalf){
innerArray.push(aGandalf);
});
}
// explicitely trigger notifications
...