Skip to content

Instantly share code, notes, and snippets.

@TakayoshiKochi
Created December 2, 2016 07:36
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 TakayoshiKochi/04fe33f40543ce07bdc53ecdfb6cc2e0 to your computer and use it in GitHub Desktop.
Save TakayoshiKochi/04fe33f40543ce07bdc53ecdfb6cc2e0 to your computer and use it in GitHub Desktop.
Benchmark for '>>>' and polyfill comparison.
<!DOCTYPE html>
<body>
<div id="root"></div>
</body>
<script>
'use strict';
if (window.testRunner) {
testRunner.dumpAsText();
}
let root = document.querySelector('#root');
// Build a DOM tree which is 4x4x4x32 = 2048 spans, 64 shadow roots
for (let i = 0; i < 4; ++i) {
let div1 = document.createElement('div');
let root1 = div1.attachShadow({mode: 'open'});
for (let j = 0; j < 4; ++j) {
let div2 = document.createElement('div');
let root2 = div2.attachShadow({mode: 'open'});
for (let k = 0; k < 4; ++k) {
let div3 = document.createElement('div');
let root3 = div3.attachShadow({mode: 'open'});
for (let l = 0; l < 32; ++l) {
let div4 = document.createElement('span');
root3.appendChild(div4);
}
root2.appendChild(div3);
}
root1.appendChild(div2);
}
root.appendChild(div1);
}
// This isn't really a polyfill for '>>>'.
function recursiveFindSpans(root, spans) {
root.querySelectorAll('*').forEach(e => {
if (e.tagName === 'SPAN')
spans.push(e);
if (e.shadowRoot)
spans = recursiveFindSpans(e.shadowRoot, spans);
});
return spans;
}
var start = window.performance.now();
for (let i = 0; i < 100; ++i) {
document.querySelectorAll('#root >>> span');
}
var end = window.performance.now();
console.log('Time :' + (end - start) + 'msec');
start = window.performance.now();
for (let i = 0; i < 100; ++i) {
recursiveFindSpans(document.querySelector('#root'), []);
}
end = window.performance.now();
console.log('Time :' + (end - start) + 'msec');
</script>
@TakayoshiKochi
Copy link
Author

CONSOLE MESSAGE: line 50: Time :29.200000000000003msec
CONSOLE MESSAGE: line 57: Time :909.35msec

@TakayoshiKochi
Copy link
Author

For comparison, the same shape of the tree without shadow roots:
https://gist.github.com/TakayoshiKochi/832b3bec7f4284d2b825cb7fd640da0d

@TakayoshiKochi
Copy link
Author

Yet another variant, with .shadow class on each shadow host:
https://gist.github.com/TakayoshiKochi/a4385510e4f483a02dd0027eb215cfe1

@TakayoshiKochi
Copy link
Author

TakayoshiKochi commented Jul 17, 2018

Note on the number of nodes:

  • shadow host + root: 2 * (4 + 44 + 44*4) = 2 * 84 = 168
  • leaf nodes: 444*32 = 2048
  • total number of nodes: 168 + 2048 = 2216
  • ratio of (shadow root) : (total number of nodes) =~ 1:26

So the speed up (29ms vs 909ms) roughly correlates the number of number of shadow roots (fast case) : number of nodes scanned (slow case).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment