YuzuJS/setImmediate

Did Safari recently throttle postMessage?

sterpe opened this issue · 13 comments

On latest Safari 7.1.2 setImmediate sort @ http://jphpsf.github.io/setImmediate-shim-demo/
performs no better (and sometimes worse) than the 4ms setTimeout. Chrome & Firefox seem
unaffected.

Does anyone know if Apple throttled their postMessage implementation down to 4ms?

Filed a bug report with Apple.

I don't have a Mac to test this with, but interesting find if so. Someone with a Mac could help investigate which mechanisms have been throttled and we could update the polyfill to work around this.

Can this be of any help?

https://github.com/petkaantonov/bluebird/blob/master/src/schedule.js

I think Bluebird's using MutationObserver on client for setImmediate..

Thank you! I should've read it first.

Apparently postMessage is indeed throttled simple test show a delay of 3 or 4ms;

var t;
window.onmessage = function () { console.log(Date.now() - t); }
function message() { t = Date.now(); window.postMessage(null, '*'); }
message() // log 3 or 4

Same goes for message channel (just in case), I don't know if we have other option here :/.

I was wondering about MessageChannel. What about the <script> onreadystatechange?

"onreadystatechange" in document.createElement("script") // false

Arggh. I am not sure what to do now :-/.

I provided Codepen example with the test of postMessage/messageChannel/setTimeout ways of providing setImmediate.
The test is at the bottom of JS:

// -------- TEST --------

  // ({}.toString.call(window.process) === "[object process]") => false (in Safari 8.0.2)
  // installNextTickImplementation => skipped

  // canUsePostMessage() => true (in Safari 8.0.2)
  window.postMessageSetImmediate = installPostMessageImplementation();
  window.postMessageSetImmediate._name = 'postMessageSetImmediate';

  // window.MessageChannel => MessageChannelConstructor (in Safari 8.0.2)
  window.messageChannelSetImmediate = installMessageChannelImplementation();
  window.messageChannelSetImmediate._name = 'messageChannelSetImmediate';

  // "onreadystatechange" in document.createElement("script") => false (in Safari 8.0.2)
  // installReadyStateChangeImplementation => skipped

  // TIMEOUT
  window.setTimeoutSetImmediate = installSetTimeoutImplementation();
  window.setTimeoutSetImmediate._name = 'setTimeoutSetImmediate';

  // TEST
  function test(method, callback) {
    var startedTime = Date.now();
    var numberOfTests = 10000;
    var testsToBeDone = numberOfTests;
    var outputResults = function () {
      console.log('"' + method._name + '" takes in average: ' +
      (Date.now() - startedTime) / numberOfTests +
      ' ms (' + numberOfTests + ' tests)');

      callback && callback();
    };
    var runTest = function () {
      testsToBeDone--;
      if (testsToBeDone) {
        method(runTest);
      } else {
        outputResults();
      }
    };
    runTest();
  }

  test(postMessageSetImmediate, function () {
    test(messageChannelSetImmediate, function () {
      test(setTimeoutSetImmediate);
    });
  });

Results for OS X Yosemite 10.10.1
Safari 8.0.2 (10600.2.5):

"postMessageSetImmediate" takes in average: 0.0319 ms (10000 tests)
"messageChannelSetImmediate" takes in average: 0.0026 ms (10000 tests)
"setTimeoutSetImmediate" takes in average: 5.1198 ms (10000 tests)

Chrome Canary 42.0.2281.0 canary (64-bit):

"postMessageSetImmediate" takes in average: 0.0941 ms (10000 tests)
"messageChannelSetImmediate" takes in average: 0.0662 ms (10000 tests)
"setTimeoutSetImmediate" takes in average: 5.0065 ms (10000 tests)

Windows 7 64bit, IE11

"postMessageSetImmediate" takes in average: 0.1531 ms (10000 tests)
"messageChannelSetImmediate" takes in average: 0.0468 ms (10000 tests)
"setTimeoutSetImmediate" takes in average: 4.5741 ms (10000 tests)

You can use Codepen cross browsers testing feature to test that/your codepen code in different browsers on OS X/Windows.

For both browsers MessageChannel method is faster than postMessage.
In Safari postMessage is more than 10 times! slower then MessageChannel.
Looks like everywhere where it is supported channel messaging works faster.
So, it might be a good idea to set MessageChannel as prior method- #42

Okay glad it's not just me. Curious if anyone has any insight into why Aplle did this?

no it's just not you I didn't do the Yosemite maj, and with osx 10.9.5 safari 7.1.2 there is a problem. I'm glad this has been fixed with the ulterior safari version.

Oh I see, so this is old Safari's problem, but new Safari is OK. In that case there is no issue!