Test name | Executions per second |
---|---|
innerHTML | 1028048.8 Ops/sec |
removechild & appendChild(cloneNode()) | 1478131.4 Ops/sec |
replaceChildren | 1065389.4 Ops/sec |
Custom deleteChildren | 1454474.9 Ops/sec |
Custom replaceChildren via append | 1322132.1 Ops/sec |
Custom replaceChildren via appendChild | 1477810.6 Ops/sec |
<style id="CSS_Style">
.expand-inline {
display: block;
padding: 0;
}
.expand-inline a {
display: block;
text-align: left;
}
.expand-inline a:hover {
background-color: rgba(0, 105, 255, 0.05);
text-decoration: none;
}
.pulsar-horizontal { display: inline-block; }
.pulsar-horizontal>div {
display: inline-block;
width: 8px;
height: 8px;
padding: 2px;
background-color: rgb(34, 136, 255);
border-radius: 100%;
animation-name: pulsing;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-fill-mode: both;
animation-duration: 1s;
}
.pulsar-horizontal>div::nth-child(1) { animation-delay: 0s; }
.pulsar-horizontal>div::nth-child(2) { animation-delay: 0.25s; }
.pulsar-horizontal>div::nth-child(3) { animation-delay: 0.5s; }
@keyframes pulsing {
0%, 100% { transform: scale(0); opacity: 0.5; }
50% { transform: scale(1); opacity: 1; }
}
</style>
<template id='ELEMENTS'>
<div class="pulsar-horizontal"><div></div><div></div><div></div></div>
<span class="expand-text">
<a href="/r/IdiotsInCars/comments/vz8iju/other_driver_said_i_hit_him_technically_true_but/ig7o5tm/">continue this thread</a>
</span>
<a href="/r/IdiotsInCars/comments/vz8iju/other_driver_said_i_hit_him_technically_true_but/ig7o5tm/">continue this thread</a>
<span class="deepthread expand-inline" data-comment-ids="ig7o5tm">
<a href="/r/IdiotsInCars/comments/vz8iju/other_driver_said_i_hit_him_technically_true_but/ig7o5tm/">continue this thread</a>
::after
<span class="gray"> (3 replies)</span>
</span>
</template>
<div id="container">
</div>
const template = document.getElementById('ELEMENTS').content;
var RESOURCES = {
pulsar: template.children[0].cloneNode(true),
pulsarStr: template.children[0].outerHTML,
expand: template.children[1].cloneNode(true),
expandStr: template.children[1].outerHTML,
a: template.children[2].cloneNode(true),
aStr: template.children[2].outerHTML,
deepthread: template.children[3].cloneNode(true),
container: document.getElementById('container'),
get deepthreads() {
return Array.from(this.container.childNodes);
},
deleteChildren(root) {
while (root.firstChild) { root.lastChild.remove(); }
return root;
},
replaceChildren_append(root, replacements) {
while (root.firstChild) { root.lastChild.remove(); }
root.append(replacements);
return root;
},
replaceChildren_appendChild(root, replacements) {
while (root.firstChild) { root.lastChild.remove(); }
for(let len=replacements.length, i=0; i<len; ++i) { root.appendChild(replacements[i]); }
return root;
},
};
for(let { container, deepthread }=RESOURCES, i = 0; i < 100; i++) {
container.appendChild(deepthread.cloneNode(true));
}
// caching vars doubles bench speed. The length of the scope chain to access values from preparation is excessive
const { container, deepthreads, pulsarStr, expandStr } = RESOURCES;
for(let len=deepthreads.length, i=0; i<len; ++i) {
deepthreads[i].innerHTML = pulsarStr;
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
deepthreads[i].innerHTML = expandStr;
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
deepthreads[i].innerHTML = '';
}
container.innerHTML = '';
// caching vars doubles bench speed. The length of the scope chain to access values from preparation is excessive
const { container, deepthreads, pulsar, expand } = RESOURCES;
for(let child, dt, len=deepthreads.length, i=0; i<len; ++i) { (dt = deepthreads[i]);
while ((child=dt.lastChild)!==null) { child.remove(); }
dt.appendChild(pulsar.cloneNode(true));
}
for(let child, dt, len=deepthreads.length, i=0; i<len; ++i) { (dt = deepthreads[i]);
while ((child=dt.lastChild)!==null) { child.remove(); }
dt.appendChild(expand.cloneNode(true));
}
for(let child, dt, len=deepthreads.length, i=0; i<len; ++i) { (dt = deepthreads[i]);
while ((child=dt.lastChild)!==null) { child.remove(); }
}
for(let child; (child=container.lastChild)!==null; ) {
child.remove()
}
// caching vars doubles bench speed. The length of the scope chain to access values from preparation is excessive
const { container, deepthreads, pulsar, expand } = RESOURCES;
for(let len=deepthreads.length, i=0; i<len; ++i) {
deepthreads[i].replaceChildren(pulsar.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
deepthreads[i].replaceChildren(expand.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
deepthreads[i].replaceChildren();
}
container.replaceChildren();
// caching vars doubles bench speed. The length of the scope chain to access values from preparation is excessive
const { container, deepthreads, pulsar, expand, deleteChildren } = RESOURCES;
for(let len=deepthreads.length, i=0; i<len; ++i) {
deleteChildren(deepthreads[i]).appendChild(pulsar.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
deleteChildren(deepthreads[i]).appendChild(expand.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
deleteChildren(deepthreads[i]);
}
deleteChildren(container);
// caching vars doubles bench speed. The length of the scope chain to access values from preparation is excessive
const { container, deepthreads, pulsar, expand, replaceChildren_append } = RESOURCES;
for(let len=deepthreads.length, i=0; i<len; ++i) {
replaceChildren_append(deepthreads[i], pulsar.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
replaceChildren_append(deepthreads[i], expand.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
replaceChildren_append(deepthreads[i]);
}
replaceChildren_append(container);
// caching vars doubles bench speed. The length of the scope chain to access values from preparation is excessive
const { container, deepthreads, pulsar, expand, replaceChildren_appendChild } = RESOURCES;
for(let len=deepthreads.length, i=0; i<len; ++i) {
replaceChildren_appendChild(deepthreads[i], pulsar.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
replaceChildren_appendChild(deepthreads[i], expand.cloneNode(true));
}
for(let len=deepthreads.length, i=0; i<len; ++i) {
replaceChildren_appendChild(deepthreads[i]);
}
replaceChildren_appendChild(container);