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
Basic DOM operation: adding and a listener to an element and then removing
As an added challenge, the - this - object must be set for the listener. This gets really ugly in jQuery.
This is an alternate version of this test:-
http://jsperf.com/adding-and-removing-listeners/
...adding legacy IE support (e.g. IE 5.5 - IE 8) and without introducing leaky circular references involving host objects.
Note that all jQuery-based scripts leak memory in legacy IE browsers until the page is unloaded (e.g. by navigation). This is a bear for sites/apps that never navigate (e.g. single page apps).
This version adds a small bit of code, which can be safely hidden in IE conditional comments (lt IE 9) as the only known browsers to feature attachEvent without addEventListener are the old MSHTML-based browsers. If others exist, they are good candidates for degradation.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
/*
* Context here is an HTML5 document
* Appropriate build for this context would exclude XHTML support
* Next line asserts document will create an HTML DOM
* There are virtually no documents on the Web that create an XHTML DOM
*
*/
var API = { disableXmlParseMode:true };
</script>
<script src="//www.cinsoft.net/mylib099-min.js"></script>
<script>
// For My Library test
var attachListener = API.attachListener;
var detachListener = API.detachListener;
// For cross-browser test
// Degrades in browsers lacking native bind method (many)
// Alternatively, use Function.prototype.call (adds back most of non-IE)
// No frames - one document only
var attachEventListener, removeAttachedEventListener;
var elHtml = document.documentElement;
if (elHtml) { // Need HTML element for feature detection
// NOTE: Should use isHostMethod for host method detection
if (elHtml.addEventListener && Function.prototype.bind) {
attachEventListener = function(el, eventType, fn, thisObject) {
var boundFunction = fn.bind(thisObject || el);
el.addEventListener(eventType, boundFunction, false);
return boundFunction; // NOTE: returns bound function for removal
};
removeAttachedEventListener = function(el, eventType, fn) {
el.removeEventListener(eventType, fn);
};
} else if (elHtml.attachEvent && Function.prototype.call) {
// Degrades under IE 5.5
// NOTE: As written for test, all variables are global.
// Wrap the whole thing in a "module" function and leaks will
// be reintroduced. The "theseObjects" variable must be global
// or a property of a global object (e.g. a "namespace" object).
// Stores references to objects used for - this - object in listeners
var theseObjects = [];
// Index for theseObjects array, bumped on each attachment
var theseObjectsIndex = 0;
attachEventListener = function(el, eventType, fn, thisObject) {
var thisObjectIndex = theseObjectsIndex++;
// Store reference to object used for - this - in listener
theseObjects[thisObjectIndex] = thisObject || el;
var boundFunction = function() {
fn.call(theseObjects[thisObjectIndex], window.event);
};
el.attachEvent('on' + eventType, boundFunction);
// Discard unneeded references
// Prevents circular references with host objects (e.g. the element)
// Prevents IE leaks related to such circular references
// No unload event cleanup required
thisObject = el = null;
return boundFunction;
};
removeAttachedEventListener = function(el, eventType, fn) {
el.detachEvent('on' + eventType, fn);
};
}
}
// For all tests
var el1 = document.createElement('div');
var el2 = document.createElement('div');
var el3 = document.createElement('div');
var el4 = document.createElement('div');
var listenerFunction = function() {
var x = 1;
};
var thisObject = {};
</script>
Ready to run.
Test | Ops/sec | |
---|---|---|
My Library |
| ready |
My Library (OO) |
| ready |
jQuery |
| ready |
Cross-browser |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.