Skip to content

Instantly share code, notes, and snippets.

@benhoyt
Created October 28, 2017 18:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benhoyt/2369a14da48dd8d3d373f90f2e35a1be to your computer and use it in GitHub Desktop.
Save benhoyt/2369a14da48dd8d3d373f90f2e35a1be to your computer and use it in GitHub Desktop.
Speed test of tiny virtual dom and merge algorithm
<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