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
<html><body>
<div></div>
<div>
<ul>
<li></li>
<li></li>
<li>got me</li>
<li></li>
</ul>
</div>
<script>
function useDomTraversal(xpath) {
var chunk = "",
element = document.documentElement,
nodeIndex = 1,
i,
j,
char;
xpath = xpath.substr("/html/".length);
for (i = 0; i < xpath.length; i++) {
char = xpath.charAt(i);
if (chunk === "") {
if (!element) {
return null;
}
element = element.firstElementChild;
}
if (char === "/" || i === xpath.length - 1) {
j = 1;
if (i === xpath.length - 1) {
chunk += char;
}
chunk = chunk.toUpperCase();
do {
if (element.nodeName === chunk) {
if (nodeIndex === j) {
break;
}
j++;
}
} while (element = element.nextElementSibling);
nodeIndex = 1;
chunk = "";
} else if (char === "[") {
nodeIndex = "";
} else if (char === "]") {
nodeIndex = parseInt(nodeIndex, 10);
} else if (typeof nodeIndex === "string") {
nodeIndex += char;
} else {
chunk += char;
}
}
return element;
}
function useQuerySelector(xpath) {
var cssSelector = "",
i,
char;
xpath = xpath.substr("/html/".length);
for (i = 0; i < xpath.length; i++) {
char = xpath.charAt(i);
if (char === "/") {
cssSelector += ">";
} else if (char === "[") {
cssSelector += ":nth-of-type(";
} else if (char === "]") {
cssSelector += ")";
} else {
cssSelector += char;
}
}
return document.querySelector(cssSelector);
}
function useCssSelector(css) {
return document.querySelectorAll(css);
}
function useNativeSelectors() {
return document.getElementsByTagName('body')[0].getElementsByTagName('div')[2].getElementsByTagName('ul')[0].getElementsByTagName('li')[2]
}
function useNativeSelector() {
return document.getElementsByTagName('div')[2].getElementsByTagName('li')[2];
};
function useDynamicString(arr) { var i=0,j=arr.length,call='document';while(i<j){ if(arr[i][0].slice(0,1)=="#"){call+='.getElementById("'+arr[i][0].slice(1,arr[i][0].length)+'")'}else if(arr[i][0].slice(0,1)=="."){call+='.getElementsByClassName("'+arr[i][0].slice(1,arr[i][0].length)+'")['+arr[i][1]+']'}else{call+='.getElementsByTagName("'+arr[i][0]+'")['+arr[i][1]+']'};i++ };return (0,eval)(call) };
function useDynamicDirectCalls(arr) { var i=0,j=arr.length,temp=document;while(i<j){ if(arr[i][0].slice(0,1)=="#"){temp=temp.getElementById(arr[i][0].slice(1,arr[i][0].length))}else if(arr[i][0].slice(0,1)=="."){temp=temp.getElementsByClassName(arr[i][0].slice(1,arr[i][0].length))[arr[i][1]]}else{temp=temp.getElementsByTagName(arr[i][0])[arr[i][1]]};i++ };return temp; };
console.log('Query sel: ',useQuerySelector("/html/body/div[2]/ul/li[3]"));
console.log('Dom trav: ',useDomTraversal("/html/body/div[2]/ul/li[3]"));
console.log('qSA css: ',useCssSelector('div:nth-of-type(2)>ul>li:nth-of-type(3)'));
console.log('Native multi: ',useNativeSelectors());
console.log('Native single: ',useNativeSelector());
console.log('Native dynamic string: ',useDynamicString([['div',2],['li',2]]));
console.log('Native dynamic direct calls: ',useDynamicDirectCalls([['div',2],['li',2]]));
</script>
</body></html>
Ready to run.
Test | Ops/sec | |
---|---|---|
query selector |
| ready |
dom traversal |
| ready |
qSA css selector |
| ready |
Native JS with all selectors in chain |
| ready |
Native JS with only the 2 needed elem selectors |
| ready |
Native JS dynamic String |
| ready |
Native JS dynamic Direct Calls |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.