Created
October 28, 2017 18:17
-
-
Save benhoyt/2369a14da48dd8d3d373f90f2e35a1be to your computer and use it in GitHub Desktop.
Speed test of tiny virtual dom and merge algorithm
This file contains 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
<html> | |
<head><title>More speed tests</title></head> | |
<body> | |
<h1>More speed tests</h1> | |
<div id="main"></div> | |
<script> | |
/* | |
<ul> | |
{% for item in items %} | |
<li>item: {{ item }}</li> | |
{% end for %} | |
</ul> | |
*/ | |
function list(items) { | |
var node1 = {tag: 'ul', attrs: {}, children: []}; | |
for (var i = 0; i < items.length; i++) { | |
var item = items[i]; | |
var node2 = {tag: 'li', attrs: {}, children: ['item: ', item]}; | |
node1.children.push(node2); | |
} | |
return node1; | |
} | |
function vnodeToDom(vnode) { | |
if (typeof vnode != 'object') { | |
return document.createTextNode(vnode); | |
} | |
var dom = document.createElement(vnode.tag); | |
for (var attr in vnode.attrs) { | |
dom.setAttribute(attr, vnode.attrs[attr]); | |
} | |
for (var i = 0; i < vnode.children.length; i++) { | |
var child = vnode.children[i]; | |
dom.appendChild(vnodeToDom(child)); | |
} | |
return dom; | |
} | |
// This basically stolen from: https://github.com/bryhoyt/emerj | |
function domMerge(dom, vnode) { | |
for (var i = 0; i < vnode.children.length; i++) { | |
var newNode = vnode.children[i]; | |
if (i >= dom.childNodes.length) { | |
dom.appendChild(vnodeToDom(newNode)); | |
continue; | |
} | |
var existing = dom.childNodes[i]; | |
var newNodeType = typeof newNode != 'object' ? Node.TEXT_NODE : Node.ELEMENT_NODE; | |
if (existing.nodeType != newNodeType) { | |
dom.replaceChild(vnodeToDom(newNode), existing); | |
} else if (newNodeType == Node.TEXT_NODE) { | |
if (existing.textContent == newNode) continue; | |
existing.textContent = newNode; | |
} else { | |
var existingAttrs = {}; | |
for (var j = 0; j < existing.attributes.length; j++) { | |
var attr = existing.attributes[j]; | |
existingAttrs[attr.name] = attr.value; | |
} | |
for (var attr in existingAttrs) { | |
if (attr in newNode.attrs) continue; | |
existing.removeAttribute(attr); | |
} | |
for (var attr in newNode.attrs) { | |
if (attr in existingAttrs && existingAttrs[attr] == newNode.attrs[attr]) continue; | |
existing.setAttribute(attr, newNode.attrs[attr]); | |
} | |
domMerge(existing, newNode) | |
} | |
} | |
while (dom.childNodes.length > vnode.children.length) { | |
dom.removeChild(dom.lastChild); | |
} | |
} | |
d = vnodeToDom(list([])); | |
console.time('t1'); | |
for (var i = 0; i < 10000; i++) { | |
var items = []; | |
for (var j = 0; j < 100; j++) { | |
items.push(Math.random().toString(36)); | |
} | |
domMerge(d, list(items)); | |
} | |
console.timeEnd('t1'); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment