Last active
September 18, 2021 03:19
-
-
Save prettydiff/b39045cacae8d8c4a3ec044e538533dc to your computer and use it in GitHub Desktop.
dom vs queryselector #jsbench #jsperf (https://jsbench.github.io/#b39045cacae8d8c4a3ec044e538533dc) #jsbench #jsperf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"/> | |
<title>dom vs queryselector #jsbench #jsperf</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script> | |
<script src="./suite.js"></script> | |
</head> | |
<body> | |
<h1>Open the console to view the results</h1> | |
<h2><code>cmd + alt + j</code> or <code>ctrl + alt + j</code></h2> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
(function (factory) { | |
if (typeof Benchmark !== "undefined") { | |
factory(Benchmark); | |
} else { | |
factory(require("benchmark")); | |
} | |
})(function (Benchmark) { | |
var suite = new Benchmark.Suite; | |
Benchmark.prototype.setup = function () { | |
const dom = function browser_dom() { | |
// getAncestor - A method to walk up the DOM towards the documentElement. | |
// * identifier: string - The string value to search for. | |
// * selector: "class", "id", "name" - The part of the element to compare the identifier against. | |
const getAncestor = function browser_dom_getAncestor(identifier, selector) { | |
// eslint-disable-next-line | |
let start = (this === document) ? document.documentElement : this; | |
const test = function browser_dom_getAncestor_test() { | |
if (selector === "class") { | |
if (start.getAttribute("class") === identifier) { | |
return true; | |
} | |
return false; | |
} | |
if (selector === "id") { | |
if (start.getAttribute("id") === identifier) { | |
return true; | |
} | |
return false; | |
} | |
if (start.nodeName.toLowerCase() === identifier) { | |
return true; | |
} | |
return false; | |
}; | |
if (start === null || start === undefined) { | |
return null; | |
} | |
if (start === document.documentElement || test() === true) { | |
return start; | |
} | |
do { | |
start = start.parentNode; | |
if (start === null) { | |
return null; | |
} | |
} while (start !== document.documentElement && test() === false); | |
return start; | |
}, | |
// getElementByAttribute - Search all descendant elements containing a matching attribute with matching value and returns an array of corresponding elements. | |
// * name: string - The name of the attribute to search for. An empty string means accept every attribute name. | |
// * value: string - The attribute value to search for. An empty string means accept any attribute value. | |
getElementsByAttribute = function browser_dom_getElementsByAttribute(name, value) { | |
// eslint-disable-next-line | |
const start = (this === document) ? document.documentElement : this, attrs = start.getNodesByType(2), out = []; | |
if (typeof name !== "string") { | |
name = ""; | |
} | |
if (typeof value !== "string") { | |
value = ""; | |
} | |
attrs.forEach(function browser_dom_getElementsByAttribute_each(item) { | |
if (item.name === name || name === "") { | |
if (item.value === value || value === "") { | |
out.push(item.ownerElement); | |
} | |
} | |
}); | |
return out; | |
}, | |
// getElementsByText - Returns an array of descendant elements containing the white space trimmed text. | |
// * textValue: string - The text to match. The value must exactly match the complete text node value after trimming white space. | |
// * castSensitive: boolean - Whether case sensitivity should apply. | |
getElementsByText = function browser_dom_getElementsByText(textValue, caseSensitive) { | |
// eslint-disable-next-line | |
const start = (this === document) ? document.documentElement : this, texts = start.getNodesByType(3), out = []; | |
if (typeof textValue !== "string") { | |
textValue = ""; | |
} | |
else { | |
textValue = textValue.replace(/^\s+/, "").replace(/\s+$/, ""); | |
} | |
if (typeof caseSensitive !== "boolean") { | |
caseSensitive = false; | |
} | |
texts.forEach(function browser_dom_getElementsByText_each(item) { | |
const text = (caseSensitive === true) | |
? item.textContent.toLowerCase() | |
: item.textContent; | |
if (textValue === "" && text.replace(/\s+/, "") !== "") { | |
out.push(item.parentElement); | |
} | |
else if (textValue !== "" && text.replace(/^\s+/, "").replace(/\s+$/, "") === textValue) { | |
out.push(item.parentElement); | |
} | |
}); | |
return out; | |
}, | |
// getNodesByType - Returns an array of DOM nodes matching the provided node type. | |
// * typeValue: string|number = The value must be a node type name or a node type number (0-12) | |
// - An empty string, "all", or 0 means gather all descendant nodes regardless of type. | |
// - For standard values see: https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType | |
getNodesByType = function browser_dom_getNodesByType(typeValue) { | |
const valueString = (typeof typeValue === "string") ? `${typeValue.toLowerCase().replace("_node", "")}_node` : "", numb = (isNaN(Number(typeValue)) === false) | |
? Math.round(Number(typeValue)) | |
: null, output = [], child = function browser_dom_getNodesByType_child(recurse) { | |
const children = recurse.childNodes, len = children.length, attributes = recurse.attributes, atLen = attributes.length; | |
let a = 0; | |
// Special functionality for attribute types. | |
if (atLen > 0 && (types === 2 || types === 0)) { | |
do { | |
output.push(attributes[a]); | |
a = a + 1; | |
} while (a < atLen); | |
} | |
a = 0; | |
if (len > 0) { | |
do { | |
if (children[a].nodeType === types || types === 0) { | |
output.push(children[a]); | |
} | |
if (children[a].nodeType === 1) { | |
//recursion magic | |
browser_dom_getNodesByType_child(children[a]); | |
} | |
a = a + 1; | |
} while (a < len); | |
} | |
}, types = (function browser_dom_getNodesByType_types() { | |
if (valueString === "element_node") { | |
return 1; | |
} | |
if (valueString === "attribute_node") { | |
return 2; | |
} | |
if (valueString === "text_node") { | |
return 3; | |
} | |
if (valueString === "cdata_section_node") { | |
return 4; | |
} | |
if (valueString === "entity_reference_node") { | |
return 5; | |
} | |
if (valueString === "entity_node") { | |
return 6; | |
} | |
if (valueString === "processing_instruction_node") { | |
return 7; | |
} | |
if (valueString === "comment_node") { | |
return 8; | |
} | |
if (valueString === "document_node") { | |
return 9; | |
} | |
if (valueString === "document_type_node") { | |
return 10; | |
} | |
if (valueString === "document_fragment_node") { | |
return 11; | |
} | |
if (valueString === "notation_node") { | |
return 12; | |
} | |
if (numb !== null && numb < 13 && numb > -1) { | |
return numb; | |
} | |
return 0; | |
}()); | |
// eslint-disable-next-line | |
child((this === document) ? document.documentElement : this); | |
return output; | |
}; | |
// Create a document method | |
document.getElementsByAttribute = getElementsByAttribute; | |
document.getNodesByType = getNodesByType; | |
document.getElementsByText = getElementsByText; | |
// Ensure dynamically created elements get these methods too | |
Element.prototype.getAncestor = getAncestor; | |
Element.prototype.getElementsByAttribute = getElementsByAttribute; | |
Element.prototype.getNodesByType = getNodesByType; | |
Element.prototype.getElementsByText = getElementsByText; | |
};dom(); | |
}; | |
suite.add("dom method - id", function () { | |
// dom method - id | |
document.getElementById("canvas"); | |
}); | |
suite.add("dom method - class", function () { | |
// dom method - class | |
document.getElementsByClassName("sa-success"); | |
}); | |
suite.add("dom method - chain by id", function () { | |
// dom method - chain by id | |
document.getElementById("canvas").getElementsByTagName("div"); | |
}); | |
suite.add("dom method - chain by class", function () { | |
// dom method - chain by class | |
document.getElementsByClassName("app")[0].getElementsByClassName("app__foot")[0].getElementsByTagName("table"); | |
}); | |
suite.add("query selector - id", function () { | |
// query selector - id | |
document.querySelector("#canvas"); | |
}); | |
suite.add("query selector - class", function () { | |
// query selector - class | |
document.querySelector(".sa-success"); | |
}); | |
suite.add("query selector - chain by id", function () { | |
// query selector - chain by id | |
document.querySelector("#canvas div"); | |
}); | |
suite.add("query selector - chain by class", function () { | |
// query selector - chain by class | |
document.querySelector(".app .app_foot table"); | |
}); | |
suite.add("query selector all - id", function () { | |
// query selector all - id | |
document.querySelectorAll("#canvas"); | |
}); | |
suite.add("query selector all - class", function () { | |
// query selector all - class | |
document.querySelectorAll(".sa-success"); | |
}); | |
suite.add("query selector all - chain by id", function () { | |
// query selector all - chain by id | |
document.querySelectorAll("#canvas div"); | |
}); | |
suite.add("query selector all - chain by class", function () { | |
// query selector all - chain by class | |
document.querySelectorAll(".app .app_foot table"); | |
}); | |
suite.add("custom dom method - getElementsByAttribute", function () { | |
// custom dom method - getElementsByAttribute | |
document.getElementsByAttribute("href"); | |
}); | |
suite.add("custom dom method - getAncestor", function () { | |
// custom dom method - getAncestor | |
document.getElementsByTagName("table")[0].getAncestor("body", "tag"); | |
}); | |
suite.add("custom dom method - getNodesByType", function () { | |
// custom dom method - getNodesByType | |
document.getNodesByType("comment"); | |
}); | |
suite.add("custom dom method - getElementsByText", function () { | |
// custom dom method - getElementsByText | |
document.getElementsByText("Run"); | |
}); | |
suite.on("cycle", function (evt) { | |
console.log(" - " + evt.target); | |
}); | |
suite.on("complete", function (evt) { | |
console.log(new Array(30).join("-")); | |
var results = evt.currentTarget.sort(function (a, b) { | |
return b.hz - a.hz; | |
}); | |
results.forEach(function (item) { | |
console.log((idx + 1) + ". " + item); | |
}); | |
}); | |
console.log("dom vs queryselector #jsbench #jsperf"); | |
console.log(new Array(30).join("-")); | |
suite.run(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment