Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I speed up knockout when populating a large observable array?

Tags:

knockout.js

I have a web app that does a SOAP request for some data and populates a knockout viewmodel with the results. I'm currently getting around 1000 line items back that have to be pushed onto my knockout viewmodel. Profiling the page in chrome shows that a large portion of the load time/CPU is spent in knockout.js. I'm wandering if there's a way to maybe delay any knockout updates/processing until all of the items are pushed into the observable array.

Edit: To be more clear, I guess I'm looking for something like delaying or throttling. But it looks like, from this answer that I might just be better off building a normal array and then populating the entire observable array, instead of pushing each item directly onto the observable array. This might remove my need to delay or throttle bindings. Any recommendations?

like image 813
xdumaine Avatar asked Feb 08 '13 13:02

xdumaine


2 Answers

If you just need to replace the contents of an observableArray, you don't need to loop through the array.

The most efficient operation is to simply set it to a new value:

this.obsArray(newData);
like image 183
Olivier Payen Avatar answered Nov 10 '22 18:11

Olivier Payen


This is probably the best approach:

function MyVM(){
    this.fooObsArray = ko.observableArray([]);
}

function Foo(){

var self = this;
self.vm = new MyVM();

this.pushSlow = function(arrayToBePushed){
    for (int i = 0; i < arrayToBePushed.length; i++){
        var element = arrayToBePushed[i];
        self.vm.fooObsArray.push(element);          //notifies ui foreach of elements => + delay
    }
}

this.pushFast = function(arrayToBePushed){
    var underlyingArray = self.vm.fooObsArray();

    for (int i = 0; i < arrayToBePushed.length; i++){
        var element = arrayToBePushed[i];
        underlyingArray.push(element);
    }

    self.vm.fooObsArray.valueHasMutated();          //notifies ui once all elements have been added => - delay
}
}
like image 7
Daniel Conde Marin Avatar answered Nov 10 '22 17:11

Daniel Conde Marin