Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
Create template vs regex
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Browser:
Chrome 131
Operating system:
Windows
Device Platform:
Desktop
Date tested:
one year ago
Test name
Executions per second
Create template
23113.7 Ops/sec
Regex
73658.8 Ops/sec
HTML Preparation code:
<!--your preparation HTML code goes here-->
Tests:
Create template
/** * Creates a virtual DOM tree from an HTML string. * * @param {string} htmlString - The HTML string to parse. * @return {Object} The root node of the virtual DOM tree. */ function createVirtualDOM(htmlString) { /** * Recursively creates a virtual DOM node from a DOM element. * * @param {Element} element - The DOM element to create a virtual node from. * @return {Object} The virtual DOM node. */ function createNode(element) { //console.log(elements) // Create a virtual DOM node with the element's tag name and attributes const node = { tagName: element.tagName, attributes: {} }; // Add the element's attributes to the virtual node for (let i = 0; i < element.attributes.length; i++) { const attribute = element.attributes[i]; node.attributes[attribute.name] = attribute.value; } // If the element has child nodes, create virtual nodes for them as well if (element.childNodes.length > 0) { node.children = []; for (let i = 0; i < element.childNodes.length; i++) { const child = element.childNodes[i]; if (child.nodeType === Node.ELEMENT_NODE) { // Recursively create a virtual node for the child element node.children.push(createNode(child)); } else if (child.nodeType === Node.TEXT_NODE) { // Skip whitespace if (child.textContent.trim().length === 0) continue; // Create a virtual node for the child text node node.children.push({ //tagName: null, text: child.textContent }); } } } return node; } var t = document.createElement('template'); t.innerHTML = `<t>${htmlString}</t>`; const nodes = []; t.content.querySelectorAll('t > *').forEach(element => nodes.push(createNode(element))); // Return the root virtual DOM node return nodes; } const vdom = createVirtualDOM(`<div> <h4>Income</h4> <p id="money-plus" class="money plus"><placeholder data-id="income"/></p> </div> <div> <h4>Expense</h4> <p id="money-minus" class="money minus"><placeholder data-id="expense"/></p> <input type="checkbox" name="testcheck" value="checkme" checked /> <div class="inner">Text <a href="#">with</a> link</div> </div>`);
Regex
lookup = { "area": true, "base": true, "br": true, "col": true, "embed": true, "hr": true, "img": true, "input": true, "link": true, "meta": true, "param": true, "source": true, "track": true, "wbr": true }; const attrRE = /\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g function parseTag(tag) { let voidElement = false const res = { tagName: '', attributes: {}, children: [], } const tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/) if (tagMatch) { res.tagName = tagMatch[1] if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === '/') { voidElement = true } } const reg = new RegExp(attrRE) let result = null for (;;) { result = reg.exec(tag) if (result === null) { break } if (!result[0].trim()) { continue } if (result[1]) { const attr = result[1].trim() let arr = [attr, true] if (attr.indexOf('=') > -1) { arr = attr.split('=') } res.attributes[arr[0]] = arr[1] reg.lastIndex-- } else if (result[2]) { res.attributes[result[2]] = result[3].trim().substring(1, result[3].length - 1) } } return [ res, voidElement ] } const tagRE = /<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g const whitespaceRE = /^\s*$/ // re-used obj for quick lookups of components const empty = Object.create(null) function parse(html) { const result = [] const arr = [] let current let level = -1 let voidElement // handle text at top level if (html.indexOf('<') !== 0) { var end = html.indexOf('<') result.push({ text: end === -1 ? html : html.substring(0, end) }) } html.replace(tagRE, (tag, index) => { let isOpen = tag.charAt(1) !== '/' const start = index + tag.length const nextChar = html.charAt(start) let parent // Skip comments if (tag.startsWith('<!--')) { // Add following text node (if any) const text = html.slice(start, html.indexOf('<', start)).trim(); if (text.length > 0) { if (level === -1) { result.push({ text }) } else { parent = arr[level] if (parent) { parent.children.push({ text }) } //arr[level + 1] = { text } } } return '' } if (isOpen) { level++ [ current, voidElement ] = parseTag(tag) if (!voidElement && nextChar && nextChar !== '<') { let text = html.slice(start, html.indexOf('<', start)).trim() if (text != '') { current.children.push({ text }) } } // if we're at root, push new base node if (level === 0) { result.push(current) } parent = arr[level - 1] if (parent) { parent.children.push(current) } arr[level] = current } if (!isOpen || voidElement) { if (level > -1 && (voidElement || current.tagName === tag.slice(2, -1))) { level-- // move current up a level to match the end tag current = level === -1 ? result : arr[level] } if (nextChar !== '<' && nextChar) { // trailing text node // if we're at the root, push a base text node. otherwise add as // a child to the current node. parent = level === -1 ? result : arr[level].children // calculate correct end of the content slice in case there's // no tag after the text node. const end = html.indexOf('<', start) let content = html.slice(start, end === -1 ? undefined : end) // if a node is nothing but whitespace, collapse it as the spec states: // https://www.w3.org/TR/html4/struct/text.html#h-9.1 if (whitespaceRE.test(content)) { content = '' } // don't add whitespace-only text nodes if they would be trailing text nodes // or if they would be leading whitespace-only text nodes: // * end > -1 indicates this is not a trailing text node // * leading node is when level is -1 and parent has length 0 if ((end > -1 && level + parent.length >= 0 && content !== '') || content !== '') { parent.push({ text: content, }) } } } }) return result } const vdom = parse(`<div> <h4>Income</h4> <p id="money-plus" class="money plus"><placeholder data-id="income"/></p> </div> <div> <h4>Expense</h4> <p id="money-minus" class="money minus"><placeholder data-id="expense"/></p> <input type="checkbox" name="testcheck" value="checkme" checked /> <div class="inner">Text <a href="#">with</a> link</div> </div>`);