Вопрос

I need a faster template engine then the builtin knockout.js one. What is the fastest and how do you set it up? Any examples on the web? I have been thinking doT.js or handlebars. I want to wait for JsRender but the performance doesnt look up to par.

Это было полезно?

Решение 3

I found out about this bug, http://bugs.jqueryui.com/ticket/6757, and had someone answer it for on another problem which fixed it.

Knockout.js and large dataset makes dropdown list slow also

Другие советы

I created a binding specifically for fast table generation: https://github.com/mbest/knockout-table.

This answer is no longer accurate. Knockout 2.2 does now support reordering of elements via the foreach binding.

The main problem with knockout and the observableArray is that all operations that modify the array cause a complete rerender of the elements below the foreach binding. If this becomes a performance bottleneck you can solve this by not moving rows around but copying their value.

The obvious way which rerenders the entire foreach on every change is like the following:

function Row(value) {
    this.value = value;
}
var model = {
    rows = ko.observableArray([new Row(1), new Row(2), new Row(3), new Row(4), new Row(5)])
}
function move(index, insertionIndex) {
    var rows = models.rows();
    // TODO Insert some clever code here
    // - remove row from rows array
    // - insert row at insertionIndex into rows array
    rows.valueHasMutated();
}

As this will redraw your entire table this is probably not what you want. A better way would be mutable Row elements that support copying:

function Row(value) {
    this.value = ko.observable(value);
}
Row.prototype.copyFrom(anotherRow) {
    this.value(anotherRow().value());
}
Row.prototype.swap(anotherRow) {
    var tmp = this.value();
    this.value(anotherRow.value());
    anotherRow.value(tmp);
}
var model = {
    rows = ko.observableArray([new Row(1), new Row(2), new Row(3), new Row(4), new Row(5)])
}
function move(index, insertionIndex) {
    var rows = models.rows();
    var tmp = new Row();
    tmp.copyFrom(rows[index]) // save the current row
    if (index < insertionIndex) {
        // move row down -> move other rows up
        for (var i=index; i<insertionIndex; i++) {
            rows[i].copyFrom(rows[i+1])
        }
    } else {
        // move row up -> move other rows down
        for (var i=index; i>insertionIndex; i--) {
            rows[i].copyFrom(rows[i-1])
        }
    }
}

Note that you no longer have to use the rows.valueHasMutated() as you are not modifying the array but change the Row objects. Therefore the foreach binding does not update and you only rerender the changed rows.

It would be cool if knockout would provide a more powerful observableArray and foreach binding handler implementation which do not need to rerender the entire template on changes. Until then this is your best bet if you want to stick with Knockout.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top