سؤال

I have a knockout project that was going super well until I started using it with more data. With datasets of under 50 records, it's great. But with sets of 200, 500 and more records, it just won't do it.

I've read everything I could on that (including Knockout.js incredibly slow under semi-large datasets) but my problem is not solvable by Templating. I'm using a SlickGrid (and can't switch to a ko.grid) and by trying to disable parts of the screen one at the time, I really think it's got something to do with the grid.

The problem occurs specifically when updating a field. It freezes the screen for a minute or more. It updates some Computeds along the way, but none of them is taking any significative time to run.

I tried throttling the Computeds to remove them from the equation, it didn't help.

Apart from paging the data to never work with more than 50ish records, any idea?

EDIT : the closest I can show is this Fiddle on which I was based : http://jsfiddle.net/rniemeyer/A9NrP/

I mostly edited the Update part :

var data = ko.utils.unwrapObservable(settings.data); //just for subscription

was heavy, I used another mechanism to subscribe the Update.

It works fine on the Fiddle but on a large scale, it doesn't. My current hypothesis is that all observables are re-evaluated after a change in one record, even those who have not changed.

هل كانت مفيدة؟

المحلول 2

I finally got it. The problem was around the DataView. I was updating it all on any change (and sometimes more often even). I built a computed observable in the ViewModel to recalculate it :

    var cachedFilterCount = 0;
    var dataViewUpdater = ko.computed(function () {
        var cachedCount = cachedFilterCount, actualCount = viewModel.filteredEmployeeList().length;
        if (cachedCount !== actualCount) {
            cachedFilterCount = actualCount;
            dataView.setItems(ko.toJS(viewModel.filteredEmployeeList), "EmployeeId");
        } else if (viewModel.vmHasChanges()) {
            _.any(filteredEmployeeList(), function (item) {
                if (item.hasChanges()) {
                    dataView.updateItem(item.EmployeeId(), ko.toJS(item));
                }
            });
        }
    });

Instead of previously doing a full dataView.setItems on any change in my base list. With that fine-grained update to the grid data, it works quick enough, and is recalculated at the right times.

Thanks again to all who pitched in.

نصائح أخرى

In knockout 3 bindings are evaluated on a single element so an update on one will not evaluate other bindings you may have.

This could be related to your issue so if you are using any older versions try to update and see if it improves your situation.

  1. If you have many bindings inside a knockout

  2. Here also Ryan Niemeyer talks about very large abservable arrays and how to optimise pushing items into them

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top