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();