Last active
January 11, 2018 22:12
-
-
Save nolanlawson/ea3ea9899d3a7f26579c1ff374f8d67b to your computer and use it in GitHub Desktop.
Event delegation benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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