jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
One node at a time version of http://jsperf.com/react-css-vs-stylesheet
Testing insertion speed for deeply nested DOM structures.
Rendered using React in the following ways:
Example taken from actual usage on irccloud.com
More tests could be added using innerHTML, DOM, jQuery.
<!-- React -->
<script src="http://fb.me/react-0.12.1.min.js"></script>
<!-- Undercore -->
<script src="http://underscorejs.org/underscore-min.js"></script>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<div id="reactInlineMountNode"></div>
<div id="reactStylesheetMountNode"></div>
<div id="jqueryInlineMountNode"></div>
<div id="jqueryStylesheetMountNode"></div>
var STYLESHEET = (function() {
// Create the <style> tag
var style = document.createElement("style");
// WebKit hack :(
style.appendChild(document.createTextNode(""));
// Add the <style> element to the page
document.head.appendChild(style);
return style.sheet;
})();
function addStyleRule(props, selector) {
// we insert an empty rule just to create a new CSSStyleRule object
// the second param is the index to insert at
// using the length property we effectively "append" the rule to the end of the sheet
var ruleIndex = STYLESHEET.insertRule(selector + " {}", STYLESHEET.cssRules.length)
// the index is the position the rule was inserted at, so we can now get a handle on it
var rule = STYLESHEET.cssRules.item(ruleIndex);
// now we have it, modify it's styles!
// applied to the document immediately
_.each(props, function (v, k) {
rule.style[k] = v;
});
}
var styleData = {
'.row': {
backgroundColor: "rgb(226, 237, 255)",
borderCollapse: "separate",
color: "rgb(51, 51, 51)",
display: "block",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "14px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "19px",
lineHeight: "17px",
overflowX: "hidden",
overflowY: "hidden",
paddingBottom: "1px",
paddingLeft: "50px",
paddingRight: "15px",
paddingTop: "1px",
whiteSpace: "pre-wrap",
width: "796px",
wordWrap: "break-word"
},
'.date': {
borderCollapse: "separate",
color: "rgb(170, 170, 170)",
display: "inline-block",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "11px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "17px",
lineHeight: "17px",
marginLeft: "-50px",
marginRight: "5px",
marginTop: "2px",
textAlign: "center",
verticalAlign: "top",
whiteSpace: "pre-wrap",
width: "45px",
wordWrap: "break-word"
},
'.title': {
borderCollapse: "separate",
color: "rgb(170, 170, 170)",
display: "inline",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "11px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "auto",
lineHeight: "17px",
textAlign: "center",
whiteSpace: "pre-wrap",
width: "auto",
wordWrap: "break-word"
},
'.g': {
borderCollapse: "separate",
color: "rgb(51, 51, 51)",
display: "block",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "14px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "17px",
left: "-999px",
lineHeight: "17px",
position: "absolute",
top: "-999px",
whiteSpace: "pre-wrap",
width: "3.90625px",
wordWrap: "break-word"
},
'.message': {
borderCollapse: "separate",
color: "rgb(51, 51, 51)",
display: "inline",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "14px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "auto",
lineHeight: "17px",
whiteSpace: "pre-wrap",
width: "auto",
wordWrap: "break-word"
},
'.authorWrap': {
borderCollapse: "separate",
color: "rgb(51, 51, 51)",
display: "inline",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "14px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "auto",
lineHeight: "17px",
whiteSpace: "pre-wrap",
width: "auto",
wordWrap: "break-word"
},
'.mode_symbol': {
borderCollapse: "separate",
color: "rgb(186, 23, 25)",
display: "none",
fontFamily: "Inconsolata, 'Ubuntu Mono', Menlo, Consolas, Courier, monospace",
fontSize: "15px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "auto",
lineHeight: "17px",
marginBottom: "0px",
marginBeft: "0px",
marginBight: "3px",
marginBop: "0px",
whiteSpace: "pre-wrap",
width: "auto",
wordWrap: "break-word"
},
'.mode_pill': {
borderCollapse: "separate",
color: "rgb(186, 23, 25)",
display: "inline",
fontFamily: "Inconsolata, 'Ubuntu Mono', Menlo, Consolas, Courier, monospace",
fontSize: "15px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "bold",
height: "auto",
lineHeight: "17px",
marginBottom: "0px",
marginBeft: "0px",
marginBight: "3px",
marginBop: "0px",
whiteSpace: "pre-wrap",
width: "auto",
wordWrap: "break-word"
},
'.bufferLink': {
borderCollapse: "separate",
color: "rgb(34, 34, 34)",
cursor: "auto",
display: "inline",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "14px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "bold",
height: "auto",
lineHeight: "17px",
textDecoration: "none",
whiteSpace: "nowrap",
width: "auto",
wordWrap: "break-word"
},
'.content': {
borderCollapse: "separate",
color: "rgb(51, 51, 51)",
display: "inline",
fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
fontSize: "14px",
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
height: "auto",
lineHeight: "17px",
whiteSpace: "pre-wrap",
width: "auto",
wordWrap: "break-word"
}
};
_.each(styleData, addStyleRule);
var ReactLogLines = React.createClass({
styled: function (className, elProps) {
elProps = elProps || {};
if (this.props.inline) {
elProps.style = styleData['.' + className];
} else {
elProps.className = className;
}
return elProps;
},
render: function () {
var lines = {};
_.each(_.range(1), function (i) {
var div = React.DOM.div(this.styled('row'),
React.DOM.span(this.styled('date'),
React.DOM.span(this.styled('title'), '17:06')
),
React.DOM.span(this.styled('g'), '\u00A0'),
React.DOM.span(this.styled('message'),
React.DOM.span(this.styled('authorWrap'),
React.DOM.span(this.styled('g'), '<'),
React.DOM.span(this.styled('mode_symbol'), '@'),
React.DOM.span(this.styled('mode_pill'), '•'),
React.DOM.a(this.styled('bufferLink', {
'href': "#"
}), 'foo'),
React.DOM.span(this.styled('g'), '>'),
'\u00A0'
),
React.DOM.span(this.styled('content'), 'bar')
)
);
lines['line-' + i] = div;
}, this);
return React.DOM.div(null, lines);
}
});
var reactLogs = React.createFactory(ReactLogLines);
var jQueryLogLines = function (props) {
this.props = props || {};
};
jQueryLogLines.prototype = {
styled: function (el, className, elProps) {
elProps = elProps || {};
el.attr(elProps);
if (this.props.inline) {
el.css(styleData['.' + className]);
} else {
el.addClass(className);
}
return el;
},
render: function () {
var lines = [];
_.each(_.range(1), function (i) {
var div = this.styled($('<div>'), 'row')
.append(this.styled($('<span>'), 'date')
.append(this.styled($('<span>'), 'title').text('17:06'))
)
.append(this.styled($('<span>'), 'g').text('\u00A0'))
.append(this.styled($('<span>'), 'message')
.append(this.styled($('<span>'), 'authorWrap')
.append(this.styled($('<span>'), 'g').text('<'))
.append(this.styled($('<span>'), 'mode_symbol').text('@'))
.append(this.styled($('<span>'), 'mode_pill').text('•'))
.append(this.styled($('<a>'), 'bufferLink', {
'href': "#"
}).text('foo'))
.append(this.styled($('<span>'), 'g').text('>'))
.append('\u00A0')
)
.append(this.styled($('<span>'), 'content').text('bar'))
);
lines.push(div);
}, this);
return $('<div>').append(lines);
}
};
var jqueryInlineLogs = new jQueryLogLines({inline: true});
var jqueryStylesheetLogs = new jQueryLogLines({inline: false});
document.getElementById('reactInlineMountNode').innerHTML = '';
document.getElementById('reactStylesheetMountNode').innerHTML = '';
document.getElementById('jqueryInlineMountNode').innerHTML = '';
document.getElementById('jqueryStylesheetMountNode').innerHTML = '';
Ready to run.
Test | Ops/sec | |
---|---|---|
React Inline |
| ready |
React Stylesheet |
| ready |
jQuery Inline |
| ready |
jQuery Stylesheet |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.