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"...