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
See http://jsperf.com/jquery-if-hasclass-then-addclass-vs-addclass/4 for an idea of how this performs without the check.
This simple patch checks if the className attr has actually changed before setting it on the element, preventing us from writing to the DOM if we don't need to.
With recent jQuery.
<script src="//code.jquery.com/jquery-2.1.1.js"></script>
<script>
// Overwrite addClass, removeClass
// from core
var core_rnotwhite = /\S+/g;
var nodeHook, boolHook,
rclass = /[\t\r\n\f]/g,
rreturn = /\r/g,
rfocusable = /^(?:input|select|textarea|button)$/i;
jQuery.fn.extend({
addClass: function( value ) {
var classes, elem, cur, clazz, j, result
i = 0,
len = this.length,
proceed = typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).addClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
// The disjunction here is for better compressibility (see removeClass)
classes = ( value || "" ).match( core_rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
cur += clazz + " ";
}
}
result = jQuery.trim( cur ); // edited here
if( result !== elem.className ){
elem.className = result;
}
}
}
}
return this;
},
removeClass: function( value ) {
var classes, elem, cur, clazz, j, result,
i = 0,
len = this.length,
proceed = arguments.length === 0 || typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).removeClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
classes = ( value || "" ).match( core_rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
// This expression is here for better compressibility (see addClass)
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
""
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
// Remove *all* instances
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
cur = cur.replace( " " + clazz + " ", " " );
}
}
result = value ? jQuery.trim( cur ) : "";
if( result !== elem.className ){ // edited here
elem.className = result;
}
}
}
}
return this;
}
});
</script>
<div id="div1">
</div>
<div id="div2" class="test2">
</div>
<div id="div3" class="test2 test3">
</div>
<div id="div4" class="test1">
</div>
<div id="div5" class="test1 test2">
</div>
<div id="div6" class="test1 test2 test3">
</div>
var div1 = $('#div1');
var div2 = $('#div2');
var div3 = $('#div3');
var div4 = $('#div4');
var div5 = $('#div5');
var div6 = $('#div6');
div1[0].className = '';
div2[0].className = 'test2';
div3[0].className = 'test2 test3';
div4[0].className = 'test1';
div5[0].className = 'test1 test2';
div6[0].className = 'test1 test2 test3';
Ready to run.
Test | Ops/sec | |
---|---|---|
if hasclass then addclass |
| ready |
addclass |
| ready |
if !hasclass then removeClass |
| ready |
removeclass |
| ready |
if !hasclass addclass multiple classes |
| ready |
addclass multiple classes |
| ready |
if hasclass removeclass multiple classes |
| ready |
removeclass multiple classes |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.