Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Test constructable stylesheet perf
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test constructable stylesheet perf</title>
<style>
pre {
position: fixed;
right: 0;
top: 0;
padding: 20px;
background: rgba(30, 30, 30, 0.8);
color: white;
pointer-events: none;
}
.form {
margin: 20px 0;
}
</style>
</head>
<body>
<h1>Test constructable stylesheet perf</h1>
<div class=form>
<label>
Number of elements:
<input id="numElements" type="number" value="1000">
</label>
</div>
<div class=form>
<label>
Number of style rules:
<input id="numRules" type="number" value="10000">
</label>
</div>
<div class=form>
<label>
Use one stylesheet in light DOM (as opposed to constructable styles in shadow DOM)
<input id="oneGlobal" type="checkbox">
</label>
</div>
<div>
<button>Render elements</button>
</div>
<div class="container"></div>
<pre style="display:none"></pre>
<script type="module">
const numOfElementsInput = document.querySelector('#numElements')
const numOfRulesInput = document.querySelector('#numRules')
const renderButton = document.querySelector('button')
const container = document.querySelector('.container')
const oneGlobalInput = document.querySelector('#oneGlobal')
const pre = document.querySelector('pre')
const log = str => {
pre.style.display = ''
pre.textContent += str + '\n'
}
function generateStyleSheet () {
const numRules = parseInt(numOfRulesInput.value, 10)
return Array(numRules).fill().map((_, i) => `[data-${i}] { color: gray }`).join('\n') +
'\n .green { color: green }'
}
renderButton.addEventListener('click', () => {
requestAnimationFrame(() => {
while (container.children.length) {
container.children[0].remove()
}
if (document.querySelector('#global')) {
document.querySelector('#global').remove()
}
const oneGlobal = oneGlobalInput.checked
let styleSheet
if (oneGlobal) {
const style = document.createElement('style')
style.textContent = generateStyleSheet()
style.id = 'global'
document.head.appendChild(style)
} else {
styleSheet = new CSSStyleSheet()
styleSheet.replaceSync(generateStyleSheet())
}
const numOfElements = parseInt(numOfElementsInput.value, 10)
for (let i = 0; i < numOfElements; i++) {
const el = document.createElement('div')
const child = document.createElement('div')
child.className = 'green'
child.textContent = 'hello'
if (oneGlobal) {
el.appendChild(child)
} else {
el.attachShadow({mode: 'open'})
el.shadowRoot.adoptedStyleSheets = [styleSheet]
el.shadowRoot.appendChild(child)
}
container.appendChild(el)
}
addEventListener('message', () => {
performance.measure('total', 'start')
log(performance.getEntriesByName('total').slice(-1)[0].duration + 'ms')
}, { once: true })
performance.mark('start')
postMessage('')
})
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment