React vs Raw dom manipulation (v14)

Revision 14 of this benchmark created by Dharmesh on


Preparation HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.1/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(new Class({
  data: data,
  selected: null
}), 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
DOM Manipulation with Templates
var data = _buildData(),
  template = function(obj) {
    return [
      '<div class="col-md-12 test-data">',
                    '< span class = "', obj.className ,'" >', obj.label,' < /span>',
                '</div >'].join('');
    },
    raw = document.getElementById("raw-original"),
    html = "";

raw.innerHTML = "";

var div;
for (var i = 0; i < data.length; i++) {
    div = document.createElement('div');
    div.innerHTML = template({
         'className': '',
         'label': data[i].label
    });
    raw.appendChild(div);
}


$(raw).on("click", ".test-data span", function() {
    $(".selected", raw).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.