JSFiddle - React, Tailwind, and code Playground
by sifriday
HTML
<script src="http://knockoutjs.com/downloads/knockout-3.2.0.js"></script>
<h1>List 1, for Methods 0, 1 and 2</h1>
<div id="list1">
<!-- ko foreach: list -->
<div>
<span data-bind="text:name"></span>
<button data-bind="click:edit">Edit</button>
</div>
<!-- /ko -->
</div>
<h1>List 2, for Method 3</h1>
<div id="list2">
</div>
<h1>List 3, for Test 4</h1>
<div id="list3">
<div data-bind='component: {name: "listitems", params: {list: list}}'></div>
</div>
<script id="list_template" type="text/html">
<!-- ko foreach: list -->
<div>
<span data-bind="text:name"></span>
<button data-bind="click:edit">Edit</button>
</div>
<!-- /ko -->
</script>
JavaScript
// Methods tested:
// 0 = straight DOM insert, for comparison
// results: 1.3s 1.2s 1.4s
// 1 = traditional knockout, like LiveQ
// results: 22.2s 22.3s 23.5s
// 2 = the detached DOM node idea
// results: 10.3s 11.7s 12.3s
// 3 = the HTML hack
// results: 1.1s 1.0s 1.1s
// 4 - a KO 3.2 component
// results: 6.4s 6.2s 6.5s
// 5 - an improved version of (2)
// resutls: 6.6s 6.4s 6.7s
// More notes about each below.
// Which method do you want to use?
// Change this variable to 0, 1, 2, 3, etc...
method = 5
// We build our big list in a temp array, for performance
// We already do this in LiveQ
// See this performance gotcha -
// http://www.knockmeout.net/2012/04/knockoutjs-performance-gotcha.html
temp = []
// This is the item. It is like the FieldViewModel in LiveQ. We will
// create a list of 10,000 of these :-)
ItemViewModel = function() {
this.name = ko.observable()
this.fromJS = function(js) {
this.name(js.name)
}
this.edit = function(data, event) {
console.log("edit! " + this.name())
}
}
// This is the list of items. It is like the FormViewModel in LiveQ. It
// holds a list of 10,000 items...
ListViewModel = function() {
this.list = ko.observableArray()
}
list_vm = new ListViewModel()
// This bit is like parsing the JSON. We will create 10,000 items
// and push them into the temporary array. This is what LiveQ does;
// it loads the fields into a temporary array before pushing them in
// one go into the list that is rendered.
for (var i = 0; i < 10000; i++) {
var item_vm = new ItemViewModel()
item_vm.fromJS({name: "foo" + i})
temp.push(item_vm)
}
// Now we have a list of 10,000 items, we can begin rendering it!
if (method == 0) {
// METHOD 0
// Just put 10,000 divs in the DOM to see how slow it is without KO
// This takes about 2 seconds on my MacBook
$("#list1").html = "";
for (var i = 0; i < 10000; i++) {
$("#list1").append($("<div><span>foo"...