Skip to content

Instantly share code, notes, and snippets.

@nolanlawson
Last active January 11, 2018 22:12
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 nolanlawson/ea3ea9899d3a7f26579c1ff374f8d67b to your computer and use it in GitHub Desktop.
Save nolanlawson/ea3ea9899d3a7f26579c1ff374f8d67b to your computer and use it in GitHub Desktop.
Event delegation benchmark
<!doctype html>
<html>
<head>
<title>Event delegation benchmark</title>
<style>
body {
max-width: 600px;
margin: 40px auto;
}
div {
margin: 20px;
}
#testArea button {
display: block;
margin: 10px;
}
</style>
</head>
<body>
<h1>Event delegation benchmark</h1>
<div>
<label for="numberOfElementsInput">Number of elements</label> <input type="number" id="numberOfElementsInput" value="10000">
</div>
<div>
<label for="useDelegationCheckbox">Use event delegation</label> <input type="checkbox" id="useDelegationCheckbox" checked="checked">
</div>
<div>
<label for="numRunsInput">Median of how many runs?</label> <input type="number" id="numRunsInput" value="5">
</div>
<div>
<label for="delayInput">Delay before adding listeners</label> <input type="number" id="delayInput" value="500">
</div>
<div>
<button type="button" id="goButton">Run test</button>
</div>
<pre id="results"></pre>
<div id="testArea"></div>
<script>
(function () {
'use strict'
var $ = document.querySelector.bind(document)
var $$ = document.querySelectorAll.bind(document)
function onClickButton(e) {
var now = performance.now()
var duration = now - e.timeStamp
$('#results').textContent += 'Took ' + duration + 'ms to receive click\n'
}
function median(values) {
values = values.sort(function (a, b) {
return a - b
})
var half = Math.floor(values.length / 2)
return values.length % 2 ? values[half] : (values[half - 1] + values[half]) / 2.0
}
function runTests(callback) {
$('#goButton').disabled = true
var numberOfElements = parseInt($('#numberOfElementsInput').value, 10)
var useDelegation = $('#useDelegationCheckbox').checked
var delay = parseInt($('#delayInput').value, 10)
var numRuns = parseInt($('#numRunsInput').value, 10)
function runTest(callback) {
clearEventListeners()
clearTestArea()
performance.mark('start_test_setup_numElements_' + numberOfElements + '_useDelegation_' + !!useDelegation)
var str = ''
for (var i = 0; i < numberOfElements; i++) {
str += '<button id="button-' + (i + 1) + '" type="button">Button #' + (i + 1) + '</button>'
}
$('#testArea').innerHTML = str
performance.mark('end_test_setup_numElements_' + numberOfElements + '_useDelegation_' + !!useDelegation)
setTimeout(function () {
var buttons = $$('#testArea button')
var testArea = $('#testArea')
performance.mark('start_addEventListener')
if (useDelegation) {
testArea.addEventListener('click', onClickButton)
} else {
for (var i = 0, len = buttons.length; i < len; i++) {
buttons[i].addEventListener('click', onClickButton)
}
}
performance.mark('end_addEventListener')
performance.measure('addEventListener', 'start_addEventListener', 'end_addEventListener')
var duration = performance.getEntriesByName('addEventListener').slice(-1)[0].duration
callback(duration)
}, delay)
}
var count = -1
var durations = []
function runNext() {
if (++count === numRuns) {
// done
$('#results').textContent += 'numElements: ' + numberOfElements + ', useDelegation: ' + useDelegation + ', time to set up listener(s): ' + median(durations) + ' ms\n'
$('#goButton').disabled = false
} else {
runTest(function (duration) {
durations.push(duration)
runNext()
})
}
}
runNext()
}
function clearEventListeners() {
var buttons = $$('#testArea button')
for (var i = 0; i < buttons.length; i++) {
buttons[i].removeEventListener('click', onClickButton)
}
$('#testArea').removeEventListener('click', onClickButton)
}
function clearTestArea() {
$('#testArea').innerHTML = ''
}
$('#goButton').addEventListener('click', runTests)
})()
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment