/
child-nodes.bench.js
107 lines (94 loc) · 3.72 KB
/
child-nodes.bench.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { Bench } from '/node_modules/tinybench/dist/index.js';
const bench = new Bench();
const html = (strings, ...exprs) => {
const template = document.createElement('template');
template.innerHTML = String.raw(strings, ...exprs);
return template.content.firstElementChild;
};
const template = replacement => html`
<div>
<div>
<p>text1<span>span_text</span>${replacement}<span>span_text</span>text3</p>
</div>
</div>
`;
const childText = template('text2');
const childComment = template('<!--text2-->');
const childSpan = template('<span data-bind>text2</span>');
const childWat = template('<w>text2</w>');
const childCreate = template('');
const cloneText = () => childText.cloneNode(true).firstElementChild.firstElementChild;
const cloneComment = () => childComment.cloneNode(true).firstElementChild.firstElementChild;
const cloneSpan = () => childSpan.cloneNode(true).querySelector('[data-bind]').firstChild;
const cloneWat = () => childWat.cloneNode(true).querySelector('w').firstChild;
const cloneWatReplace = () => childWat.cloneNode(true).querySelector('w');
const list = document.createElement('div');
const size = 10000;
for(let i = 0; i < size; i++) {
const item = childComment.cloneNode(true);
item.id = `fw-node-${i}`;
item.dataset.id = `fw-node-${i}`;
list.append(item);
}
document.body.append(list);
console.log(document.getElementById(`fw-node-5000`))
console.log(list.querySelector(`#fw-node-5000`))
const pooled = childComment.cloneNode(true);
const pool = [pooled];
const adoptPool = () => (pool[0] = pool[0]).firstElementChild.firstElementChild;
const adoptFlyweight = () => document.getElementById(`fw-node-5000`).firstElementChild.firstElementChild;
const adoptFlyweight2 = () => list.querySelector(`#fw-node-5000`).firstElementChild.firstElementChild;
// const flyweight = () =>
// const spanText = cloneSpan();
// let proto = spanText;
// // eslint-disable-next-line no-cond-assign
// while(proto = Object.getPrototypeOf(proto)) {
// console.dir(proto);
// if(Object.hasOwn(proto, 'data')) { console.log(proto); }
const benchmark = true;
if(benchmark) {
bench
.add('childNodes:text', () => {
cloneText().childNodes[2].data = 'new value';
})
.add('childNodes:comment', () => {
cloneComment().childNodes[2].data = 'new value';
})
.add('adoptPool:comment', () => {
adoptPool().childNodes[2].data = 'new value';
})
.add('adoptFlyweight:comment', () => {
adoptFlyweight().childNodes[2].data = 'new value';
})
.add('adoptFlyweight2:comment', () => {
adoptFlyweight2().childNodes[2].data = 'new value';
})
.add('sibling props:text', () => {
cloneText().firstChild.nextSibling.nextSibling.data = 'new value';
})
.add('sibling props:comment', () => {
cloneComment().firstChild.nextSibling.nextSibling.data = 'new value';
})
.add('span injection', () => {
cloneSpan().data = 'new value';
})
.add('reflect span injection call', () => {
const node = cloneSpan();
Reflect.set(node, 'data', 'new value', node);
})
.add('wat injection', () => {
cloneWat().data = 'new value';
})
.add('wat replace', () => {
cloneWatReplace().replaceWith(document.createTextNode('new value'));
});
await bench.warmup(); // make results more reliable, ref: https://github.com/tinylibs/tinybench/pull/50
await bench.run();
const tabulation = bench.table();
console.table(tabulation);
console.table(
bench.todos.map(({ name }) => ({
'Task name': name,
})),
);
}