React vs Raw dom manipulation (v25)

Revision 25 of this benchmark created on


Preparation HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/html" id="raw-template">
            <div class="row">
                <div class="col-md-12 test-data">
                    <span class="{{className}}">{{label}}</span>
                </div>
            </div>
        </script>

<div id="raw-react" style="display:none;"></div>
<div id="raw-revision" style="display:none;"></div>
<div id="raw-original" style="display:none;"></div>

Setup

function _buildData(count) {
      count = count || 1000;
      var adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"];
      var colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
      var nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
      var data = [];
      for (var i = 0; i < count; i++) {
        data.push({
          id: i + 1,
          label: adjectives[_random(adjectives.length)] + " " + colours[_random(colours.length)] + " " + nouns[_random(nouns.length)]
        });
      }
      return data;
    }
    
    function _random(max) {
      return Math.round(Math.random() * 1000) % max;
    }

Test runner

Ready to run.

Testing in
TestOps/sec
React
var Class = React.createClass({
  select: function(data) {
    this.props.selected = data.id;
    this.forceUpdate();
  },
  render: function() {
    var items = [];
    for (var i = 0; i < this.props.data.length; i++) {
      items.push(React.createElement("div", {
          className: "row"
        },
        React.createElement("div", {
            className: "col-md-12 test-data"
          },
          React.createElement("span", {
            className: this.props.selected === this.props.data[i].id ? "selected" : "",
            onClick: this.select.bind(null, this.props.data[i])
          }, this.props.data[i].label)
        )
      ));
    }

    return React.createElement("div", null, items);
  }
});

var data = _buildData();

React.render(Class, document.querySelector('#raw-react'));
ready
Optimized DOM Manipulation
var fragment = document.createDocumentFragment(),
   $raw = document.querySelector('#raw-revision'),
   data = _buildData();

data.forEach(function(row) {
 var rowDiv   = document.createElement('div');
 var innerDiv = document.createElement('div');
 var span     = document.createElement('span');

 rowDiv.className   = 'row';
 innerDiv.className = 'col-md-12 test-data';
 span.textContent   = row.label;

 rowDiv.appendChild(innerDiv);
 innerDiv.appendChild(span);

 fragment.appendChild(rowDiv);
});

$raw.appendChild(fragment);

$raw.addEventListener('click', function(e) {
 if (e.currentTarget.className === 'span') {
   document.querySelector('.selected').className = '';
   e.currentTarget.className = 'selected';
 }
});
ready
Original DOM Manipulation Code
var data = _buildData(),
    template = $("#raw-template").html(),
    html = "";

document.getElementById("raw-original").innerHTML = "";

for (var i = 0; i < data.length; i++) {
    var render = template;
    render = render.replace("{{className}}", "");
    render = render.replace("{{label}}", data[i].label);
    html += render;
}

document.getElementById("raw-original").innerHTML = html;

$("#raw").on("click", ".test-data span", function() {
    $("#raw .selected").removeClass("selected");
    $(this).addClass("selected");
});
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.