Reputation: 24325
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.
Upvotes: 3
Views: 3231
Reputation: 24325
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
Upvotes: 1
Reputation: 7487
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.
Upvotes: 2
Reputation: 16688
I created a binding specifically for fast table generation: https://github.com/mbest/knockout-table.
Upvotes: 3