0

Why is setTimeout so non-performant?

I've got 100 tasks that should take 1ms each. I'm interleaving them with requestAnimationFrame which should be around 16ms. So, I'd expect to see 14-16 of these tasks to execute for each rAF. Instead I see 1-3 per rAF.

var count = 0;
var limit = 100;

function doSomething1ms() {
  var start = performance.now();
  while (performance.now() - start < 1);
  log("finished: " + count);
  if (++count < limit) {
    setTimeout(doSomething1ms, 0);
  }
}
doSomething1ms();
  
var rafCount = 100;
function raf() {
  log("raf");
  --rafCount;
  if (rafCount) {
    requestAnimationFrame(raf);
  }
};
requestAnimationFrame(raf);

log("start------------------------");

function log(msg) {
  var div = document.createElement('div');
  div.appendChild(document.createTextNode(msg));
  document.body.appendChild(div);
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
gman
  • 100,619
  • 31
  • 269
  • 393
  • Have a look at [Why in this case native promises seems to be faster than callbacks in chrome?](http://stackoverflow.com/a/22759890/1048572) – Bergi Apr 15 '16 at 10:24
  • Unfortunately promises don't go through the event queue so if I use chained promises raf doesn't execute – gman Apr 15 '16 at 10:40
  • Yes, but try some of the other techniques linked there, like `postMessage` or `setImmediate` – Bergi Apr 15 '16 at 10:45

1 Answers1

0

Based on bergi's comment and link setTimeout has a limit of 4ms

Using postMessage I get 7-10 calls per rAF which is better though still far short of 16.

var count = 0;
var limit = 100;

function doSomething1ms() {
  var start = performance.now();
  while (performance.now() - start < 1);
  log("finished: " + count);
  queueNext();
}

window.addEventListener('message', doSomething1ms);

function queueNext() {
  if (++count < limit) {
    window.postMessage({}, "*", []);
  }
}
queueNext();
  
var rafCount = 100;
function raf() {
  log("raf");
  --rafCount;
  if (rafCount) {
    requestAnimationFrame(raf);
  }
};
requestAnimationFrame(raf);

log("start------------------------");

function log(msg) {
  var div = document.createElement('div');
  div.appendChild(document.createTextNode(msg));
  document.body.appendChild(div);
}
gman
  • 100,619
  • 31
  • 269
  • 393