1

I have a web application that uses Knockout 3.4 and other libraries (inversifyJS, knockout.validation, axios, jQuery).

Since yesterday I have a huge performance issue while trying to fill a select-list asynchronous with axios and a knockout observable array.

Here is simplified jsfiddle that shows what I'm doing:

https://jsfiddle.net/m2r9Ljb2/3/

// Constructor for an object with two properties
var Country = function(name, population) {
  this.email = name;
  this.countryPopulation = population;
};

var viewModel = {
  availableCountries : ko.observableArray([]),
  selectedCountry : ko.observable() // Nothing selected by default
};
ko.applyBindings(viewModel);

$.getJSON('https://jsonplaceholder.typicode.com/comments', function( data ) {
    ko.utils.arrayPushAll(viewModel.availableCountries, data);
})

If I run this code in jsfiddle it performs really fast. If I insert this code into my application it takes over 6 seconds before the UI is responsive again in IE11 and Firefox.

Nothing seems to help and I don't know what I can do anymore. I tried "Rate-limiting" and "Deferred updates" but nothing changes.

Does someone have an idea what the problem is? Is there something I can do to debug the problem? Why does it behave differently in jsfiddle?

Shamshiel
  • 2,051
  • 3
  • 31
  • 50
  • select list html element is somehow styled with css? Rendering performance is not always related with js issues. If you have some rich design for that select list or elements around that the display calculations can also slow things down. remove styling and check again. – jgasiorowski Feb 09 '18 at 14:48
  • https://github.com/krausest/js-framework-benchmark/issues/256 – Roy J Feb 09 '18 at 17:49
  • https://stackoverflow.com/questions/9967976/update-knockout-js-observable-from-json – Roy J Feb 09 '18 at 17:50
  • Already tried to remove the styling but it didn't help. I also tried to change the method how to fill my observable array. None of the available methods change anything. If I fill the select list with jQuery (without knockout) it still is really slow. I can see in the browser developer tools that a method "searchPseudoElements" is the reason for the bad performance. – Shamshiel Feb 12 '18 at 06:25

1 Answers1

1

Unless you're adding to the array why not just try

 viewModel.availableCountries(data);

or

 ko.utils.arrayPushAll(viewModel.availableCountries(),data); 
 viewModel.availableCountries.valueHasMutated(); 
Leon
  • 616
  • 1
  • 6
  • 10
  • 1
    Can you explain the benefit of doing either of these? It appears he's already using the `arrayPushAll` utility function. – Jason Spake Feb 09 '18 at 16:55
  • @JasonSpake viewModel.availableCountries(data); will overwrite the array with the new array and the subscribers will be notified. viewModel.availableCountries.push(data) will add to the end of the array and this will notify any subscribers. if we use ko.utils.arrayPushAll we would need to call valueHasMutated() on the observableArray to notify the subcribers. – Leon Feb 12 '18 at 10:27
  • @RoyJ Cheers, I'll modify the answer. – Leon Feb 12 '18 at 10:29