React vs Raw dom manipulation (v17)

Revision 17 of this benchmark created by Denis 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"></div>
<div id="raw_optimized_dom"></div>
<div id="raw_original_dom"></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.getElementById('raw_optimized_dom'),
     parentRow = document.createElement('div'),
     testData = document.createElement('div'),
     spanEl = document.createElement('span'),
     data = _buildData();

   parentRow.className = 'row';
   testData.className = 'col-md-12 test-data';

   for (var i = 0, l = data.length; i < l; i++) {
     var row = parentRow.cloneNode(false);
     var col = testData.cloneNode(false);
     var span = spanEl.cloneNode(false);
     span.textContent = data[i].label;
     col.appendChild(span);
     row.appendChild(col);
     fragment.appendChild(row);
   }

   $raw.appendChild(fragment);

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

document.getElementById("raw_original_dom").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_dom").innerHTML = html;

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