Last active
April 30, 2020 22:03
-
-
Save jridgewell/9554bc2ae3e2234ba0b2e0bd11fc755f to your computer and use it in GitHub Desktop.
Subclassing custom elements (https://jsbench.github.io/#9554bc2ae3e2234ba0b2e0bd11fc755f) #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>Subclassing custom elements</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script> | |
| <style> | |
| body { | |
| font-size: 20px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Open the console to view the results</h1> | |
| <h2><code>cmd + alt + j</code> or <code>ctrl + alt + j</code></h2> | |
| <script src="./suite.js"></script> | |
| </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 () { | |
| if (!customElements.get("x-call-local")) { | |
| const HTMLElement = window.HTMLElement; | |
| const cache = Object.create(null); | |
| function WrappedHTMLElement(name) { | |
| return ( | |
| // cache[name] || | |
| (/*cache[name] =*/ Reflect.construct(HTMLElement, [], this.constructor)) | |
| ); | |
| } | |
| Object.setPrototypeOf(WrappedHTMLElement, HTMLElement); | |
| Object.setPrototypeOf( | |
| WrappedHTMLElement.prototype, | |
| HTMLElement.prototype | |
| ); | |
| window.HTMLElement = WrappedHTMLElement; | |
| function BaseCustomElementLocalName(name) { | |
| const _this = WrappedHTMLElement.call(this, name) || this; | |
| _this.createdCallback(); | |
| return _this; | |
| } | |
| BaseCustomElementLocalName.prototype.createdCallback = function () { | |
| this.x = this.localName; | |
| }; | |
| Object.setPrototypeOf(BaseCustomElementLocalName, WrappedHTMLElement); | |
| Object.setPrototypeOf( | |
| BaseCustomElementLocalName.prototype, | |
| WrappedHTMLElement.prototype | |
| ); | |
| window.CustomElementWithCallLocalName = function CustomElementWithCallLocalName( | |
| name | |
| ) { | |
| return BaseCustomElementLocalName.call(this, name) || this; | |
| }; | |
| Object.setPrototypeOf( | |
| CustomElementWithCallLocalName, | |
| BaseCustomElementLocalName | |
| ); | |
| Object.setPrototypeOf( | |
| CustomElementWithCallLocalName.prototype, | |
| BaseCustomElementLocalName.prototype | |
| ); | |
| window.CustomElementWithApplyLocalName = function CustomElementWithApplyLocalName() { | |
| return BaseCustomElementLocalName.apply(this, arguments) || this; | |
| }; | |
| Object.setPrototypeOf( | |
| CustomElementWithApplyLocalName, | |
| BaseCustomElementLocalName | |
| ); | |
| Object.setPrototypeOf( | |
| CustomElementWithApplyLocalName.prototype, | |
| BaseCustomElementLocalName.prototype | |
| ); | |
| function BaseCustomElementElementName(name) { | |
| const _this = WrappedHTMLElement.call(this, name) || this; | |
| _this.createdCallback(); | |
| return _this; | |
| } | |
| BaseCustomElementElementName.prototype.createdCallback = function () { | |
| this.x = this.elementName(); | |
| }; | |
| Object.setPrototypeOf(BaseCustomElementElementName, WrappedHTMLElement); | |
| Object.setPrototypeOf( | |
| BaseCustomElementElementName.prototype, | |
| WrappedHTMLElement.prototype | |
| ); | |
| window.CustomElementWithCallElementName = function CustomElementWithCallElementName( | |
| name | |
| ) { | |
| return BaseCustomElementElementName.call(this, name) || this; | |
| }; | |
| CustomElementWithCallElementName.prototype.elementName = function () { | |
| return "x-call-element"; | |
| }; | |
| Object.setPrototypeOf( | |
| CustomElementWithCallElementName, | |
| BaseCustomElementElementName | |
| ); | |
| Object.setPrototypeOf( | |
| CustomElementWithCallElementName.prototype, | |
| BaseCustomElementElementName.prototype | |
| ); | |
| window.CustomElementWithApplyElementName = function CustomElementWithApplyElementName() { | |
| return BaseCustomElementElementName.apply(this, arguments) || this; | |
| }; | |
| CustomElementWithApplyElementName.prototype.elementName = function () { | |
| return "x-apply-element"; | |
| }; | |
| Object.setPrototypeOf( | |
| CustomElementWithApplyElementName, | |
| BaseCustomElementElementName | |
| ); | |
| Object.setPrototypeOf( | |
| CustomElementWithApplyElementName.prototype, | |
| BaseCustomElementElementName.prototype | |
| ); | |
| customElements.define("x-call-local", CustomElementWithCallLocalName); | |
| customElements.define("x-apply-local", CustomElementWithApplyLocalName); | |
| customElements.define("x-call-element", CustomElementWithCallElementName); | |
| customElements.define( | |
| "x-apply-element", | |
| CustomElementWithApplyElementName | |
| ); | |
| } | |
| // }; | |
| const suites = [ | |
| [ | |
| "new CustomElementWithCallLocalName();", | |
| function () { | |
| new CustomElementWithCallLocalName("x-call-local"); | |
| // document.createElement('x-call-local'); | |
| }, | |
| ], | |
| [ | |
| "new CustomElementWithCallElementName();", | |
| function () { | |
| new CustomElementWithCallElementName("x-call-element"); | |
| // document.createElement('x-call-element'); | |
| }, | |
| ], | |
| [ | |
| "new CustomElementWithApplyLocalName();", | |
| function () { | |
| new CustomElementWithApplyLocalName("x-apply-local"); | |
| // document.createElement('x-apply-local'); | |
| }, | |
| ], | |
| [ | |
| "new CustomElementWithApplyElementName();", | |
| function () { | |
| new CustomElementWithApplyElementName("x-apply-element"); | |
| // document.createElement('x-apply-element'); | |
| }, | |
| ], | |
| ]; | |
| function shuffle(array) { | |
| const length = array == null ? 0 : array.length; | |
| if (!length) { | |
| return []; | |
| } | |
| let index = -1; | |
| const lastIndex = length - 1; | |
| const result = array.slice(); | |
| while (++index < length) { | |
| const rand = index + Math.floor(Math.random() * (lastIndex - index + 1)); | |
| const value = result[rand]; | |
| result[rand] = result[index]; | |
| result[index] = value; | |
| } | |
| return result; | |
| } | |
| shuffle(suites).forEach(function (s) { | |
| suite.add(s[0], s[1]); | |
| }); | |
| for (let i = 0; i < 1000; i++) { | |
| shuffle(suites).forEach(function (s) { | |
| s[1](); | |
| }); | |
| } | |
| 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 = results.map(function (item, idx) { | |
| return idx + 1 + ". " + item; | |
| }); | |
| document.body.innerHTML = `<pre>${results.join("\n")}`; | |
| }); | |
| console.log("Subclassing custom elements"); | |
| 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