JSFiddle - React, Tailwind, and code Playground
HTML
<label><input type="checkbox" id="useSetTimeout">Schedule main loop through setTimeout(0)</label>
<label style="right: 10px"><input type="checkbox" id="useConsoleLog">Log the details in console</label>
<div id="pointer"/>
CSS
html {
height: 100%;
}
body {
min-height: 100%;
background-color: darkblue;
}
label {
position: absolute;
color: silver;
z-index: 1;
}
#pointer {
width: 20px;
height: 20px;
position: absolute;
transform: translate(-50%, -50%);
background-color: white;
}
JavaScript
var useSetTimeout = false;
document.getElementById('useSetTimeout').onchange = function() { useSetTimeout = this.checked; }
var useConsoleLog = false;
document.getElementById('useConsoleLog').onchange = function() { useConsoleLog = this.checked; }
function consoleLog(msg) {
if (useConsoleLog)
console.log('[' + performance.now().toFixed(2) + '] '+ msg);
}
var mouse = {x: 0, y: 0};
document.body.onmousemove = function(e) {
consoleLog('process onmousemove with timeStamp: ' + e.timeStamp.toFixed(2) + ' MOUSE PROCESSING DELAY: ' + (performance.now() - e.timeStamp).toFixed(2));
document.avgDelay += (performance.now() - e.timeStamp);
document.avgCount++;
mouse.x = e.clientX;
mouse.y = e.clientY;
}
var fps = 20;
function mainLoop_userCode() {
// here some heavy user computation throttles CPU down to about specified fps
for(var complete = performance.now() + 1000 / fps; performance.now() < complete;);
}
function mainLoop_render() {
var pointer = document.getElementById('pointer');
pointer.style.left = mouse.x + 'px';
pointer.style.top = mouse.y + 'px';
}
function mainLoop_scheduler() {
consoleLog('initiate requestAnimationFrame');
requestAnimationFrame(function(e) {
consoleLog('process requestAnimationFrame with timeStamp: ' + e.toFixed(2));
useSetTimeout ? setTimeout(mainLoop_runner,0) : mainLoop_runner();
});
};
function mainLoop_runner() {
consoleLog('enter mainLoop_runner');
mainLoop_userCode();
mainLoop_render();
mainLoop_scheduler();
};
document.avgDelay = 0;
document.avgCount = 0;
mainLoop_scheduler();